mirror of https://github.com/perkeep/perkeep.git
picasa, picago: support video, change struct definitions, add start of more tests
This commit is contained in:
parent
1763efbefe
commit
29c63cc2ab
pkg/importer/picasa
third_party/github.com/tgulacsi/picago
|
@ -17,9 +17,6 @@ limitations under the License.
|
|||
// Package picasa implements an importer for picasa.com accounts.
|
||||
package picasa
|
||||
|
||||
// TODO: videos don't import correctly. it currently imports a still
|
||||
// preview frame from the video, instead of the video bytes.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -55,7 +52,7 @@ const (
|
|||
// complete run. Otherwise, if the importer runs to
|
||||
// completion, this version number is recorded on the account
|
||||
// permanode and subsequent importers can stop early.
|
||||
runCompleteVersion = "1"
|
||||
runCompleteVersion = "2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -124,7 +124,7 @@ func fakeAlbum(counter int) picago.Entry {
|
|||
author := picago.Author{
|
||||
Name: "fakeAuthorName",
|
||||
}
|
||||
media := picago.Media{
|
||||
media := &picago.Media{
|
||||
Description: "fakeAlbumDescription",
|
||||
Keywords: "fakeKeyword1,fakeKeyword2",
|
||||
}
|
||||
|
@ -186,11 +186,11 @@ func fakePhotoEntry(photoNbr int, albumNbr int) picago.Entry {
|
|||
URL: "https://camlistore.org/pic/pudgy2.png",
|
||||
Type: "image/png",
|
||||
}
|
||||
media := picago.Media{
|
||||
media := &picago.Media{
|
||||
Title: "fakePhotoTitle",
|
||||
Description: "fakePhotoDescription",
|
||||
Keywords: "fakeKeyword1,fakeKeyword2",
|
||||
Content: mediaContent,
|
||||
Content: []picago.MediaContent{mediaContent},
|
||||
}
|
||||
// to be consistent, all the pics times should be anterior to their respective albums times. whatever.
|
||||
day := time.Hour * 24
|
||||
|
@ -199,7 +199,7 @@ func fakePhotoEntry(photoNbr int, albumNbr int) picago.Entry {
|
|||
published := created.Add(day)
|
||||
updated := published.Add(day)
|
||||
|
||||
exif := picago.Exif{
|
||||
exif := &picago.Exif{
|
||||
FStop: 7.7,
|
||||
Make: "whatisthis?", // not obvious to me, needs doc in picago
|
||||
Model: "potato",
|
||||
|
|
|
@ -40,8 +40,8 @@ type Entry struct {
|
|||
Location string `xml:"http://schemas.google.com/photos/2007 location"`
|
||||
NumPhotos int `xml:"numphotos"`
|
||||
Content EntryContent `xml:"content"`
|
||||
Media Media `xml:"group"`
|
||||
Exif Exif `xml:"tags"`
|
||||
Media *Media `xml:"group"`
|
||||
Exif *Exif `xml:"tags"`
|
||||
Point string `xml:"where>Point>pos"`
|
||||
}
|
||||
|
||||
|
@ -64,15 +64,19 @@ type Link struct {
|
|||
}
|
||||
|
||||
type Media struct {
|
||||
Title string `xml:"http://search.yahoo.com/mrss title"`
|
||||
Description string `xml:"description"`
|
||||
Keywords string `xml:"keywords"`
|
||||
Content MediaContent `xml:"content"`
|
||||
Title string `xml:"http://search.yahoo.com/mrss title"`
|
||||
Description string `xml:"description"`
|
||||
Keywords string `xml:"keywords"`
|
||||
Content []MediaContent `xml:"content"`
|
||||
Thumbnail []MediaContent `xml:"thumbnail"`
|
||||
}
|
||||
|
||||
type MediaContent struct {
|
||||
URL string `xml:"url,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
URL string `xml:"url,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
Width int `xml:"width,attr"`
|
||||
Height int `xml:"height,attr"`
|
||||
Medium string `xml:"medium,attr"` // "image" or "video" for Picasa at least
|
||||
}
|
||||
|
||||
type EntryContent struct {
|
||||
|
|
|
@ -6,6 +6,7 @@ package picago
|
|||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -250,3 +251,39 @@ func TestAtom(t *testing.T) {
|
|||
t.Logf("result: %#v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseAtom(t *testing.T, file string) *Atom {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
a := new(Atom)
|
||||
if err := xml.NewDecoder(f).Decode(a); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func TestVideoInGallery(t *testing.T) {
|
||||
atom := mustParseAtom(t, "testdata/gallery-with-a-video.xml")
|
||||
if len(atom.Entries) != 3 {
|
||||
t.Fatalf("num entries = %d; want 3", len(atom.Entries))
|
||||
}
|
||||
p, err := atom.Entries[2].photo()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if p.Type != "video/mpeg4" {
|
||||
t.Errorf("type = %q; want video/mpeg4", p.Type)
|
||||
}
|
||||
if got, want := p.URL, "https://foo.googlevideo.com/bar.mp4"; got != want {
|
||||
t.Errorf("URL = %q; want %q", got, want)
|
||||
}
|
||||
|
||||
for i, ent := range atom.Entries {
|
||||
t.Logf("%d. Media = %#v", i, ent.Media)
|
||||
p, _ := ent.photo()
|
||||
t.Logf("%d. %#v", i, p)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
neturl "net/url"
|
||||
"os"
|
||||
|
@ -26,7 +25,7 @@ const (
|
|||
userURL = "https://picasaweb.google.com/data/feed/api/user/{userID}/contacts?kind=user"
|
||||
)
|
||||
|
||||
var DebugDir string
|
||||
var DebugDir = os.Getenv("PICAGO_DEBUG_DIR")
|
||||
|
||||
type User struct {
|
||||
ID, URI, Name, Thumbnail string
|
||||
|
@ -40,13 +39,27 @@ type Album struct {
|
|||
URL string
|
||||
}
|
||||
|
||||
// A Photo is a photo (or video) in a Picasaweb (or G+) gallery.
|
||||
type Photo struct {
|
||||
ID, Title, Summary, Description, Location string
|
||||
Keywords []string
|
||||
Published, Updated time.Time
|
||||
Latitude, Longitude float64
|
||||
URL, Type string
|
||||
Exif Exif
|
||||
ID, Title, Summary, Description string
|
||||
Keywords []string
|
||||
Published, Updated time.Time
|
||||
|
||||
// Latitude and Longitude optionally contain the GPS coordinates
|
||||
// of the photo.
|
||||
Latitude, Longitude float64
|
||||
|
||||
// Location is free-form text describing the location of the
|
||||
// photo.
|
||||
Location string
|
||||
|
||||
// URL is the URL of the photo or video.
|
||||
URL string
|
||||
|
||||
// Type is the Content-Type.
|
||||
Type string
|
||||
|
||||
Exif *Exif
|
||||
}
|
||||
|
||||
// Filename returns the filename of the photo (from title or ID + type).
|
||||
|
@ -111,16 +124,22 @@ func getAlbums(albums []Album, client *http.Client, url string, startIndex int)
|
|||
break
|
||||
}
|
||||
}
|
||||
var des string
|
||||
var kw []string
|
||||
if entry.Media != nil {
|
||||
des = entry.Media.Description
|
||||
kw = strings.Split(entry.Media.Keywords, ",")
|
||||
}
|
||||
albums = append(albums, Album{
|
||||
ID: entry.ID,
|
||||
Name: entry.Name,
|
||||
Summary: entry.Summary,
|
||||
Title: entry.Title,
|
||||
Description: entry.Media.Description,
|
||||
Description: des,
|
||||
Location: entry.Location,
|
||||
AuthorName: entry.Author.Name,
|
||||
AuthorURI: entry.Author.URI,
|
||||
Keywords: strings.Split(entry.Media.Keywords, ","),
|
||||
Keywords: kw,
|
||||
Published: entry.Published,
|
||||
Updated: entry.Updated,
|
||||
URL: albumURL,
|
||||
|
@ -162,55 +181,85 @@ func getPhotos(photos []Photo, client *http.Client, url string, startIndex int)
|
|||
if len(feed.Entries) == 0 {
|
||||
return nil, false, nil
|
||||
}
|
||||
if cap(photos)-len(photos) < len(feed.Entries) {
|
||||
photos = append(photos, make([]Photo, 0, len(feed.Entries))...)
|
||||
}
|
||||
for _, entry := range feed.Entries {
|
||||
var lat, long float64
|
||||
i := strings.Index(entry.Point, " ")
|
||||
if i >= 1 {
|
||||
lat, err = strconv.ParseFloat(entry.Point[:i], 64)
|
||||
if err != nil {
|
||||
log.Printf("cannot parse %q as latitude: %v", entry.Point[:i], err)
|
||||
}
|
||||
long, err = strconv.ParseFloat(entry.Point[i+1:], 64)
|
||||
if err != nil {
|
||||
log.Printf("cannot parse %q as longitude: %v", entry.Point[i+1:], err)
|
||||
}
|
||||
p, err := entry.photo()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if entry.Point != "" && lat == 0 && long == 0 {
|
||||
log.Fatalf("point=%q but couldn't parse it as lat/long", entry.Point)
|
||||
}
|
||||
url, typ := entry.Content.URL, entry.Content.Type
|
||||
if url == "" {
|
||||
url, typ = entry.Media.Content.URL, entry.Media.Content.Type
|
||||
}
|
||||
title := entry.Title
|
||||
if title == "" {
|
||||
title = entry.Media.Title
|
||||
}
|
||||
photos = append(photos, Photo{
|
||||
ID: entry.ID,
|
||||
Exif: entry.Exif,
|
||||
Summary: entry.Summary,
|
||||
Title: title,
|
||||
Description: entry.Media.Description,
|
||||
Location: entry.Location,
|
||||
//AuthorName: entry.Author.Name,
|
||||
//AuthorURI: entry.Author.URI,
|
||||
Keywords: strings.Split(entry.Media.Keywords, ","),
|
||||
Published: entry.Published,
|
||||
Updated: entry.Updated,
|
||||
URL: url,
|
||||
Type: typ,
|
||||
Latitude: lat,
|
||||
Longitude: long,
|
||||
})
|
||||
photos = append(photos, p)
|
||||
}
|
||||
// startIndex starts with 1, we need to compensate for it.
|
||||
return photos, startIndex+len(feed.Entries) <= feed.NumPhotos, nil
|
||||
}
|
||||
|
||||
func (e *Entry) photo() (p Photo, err error) {
|
||||
var lat, long float64
|
||||
i := strings.Index(e.Point, " ")
|
||||
if i >= 1 {
|
||||
lat, err = strconv.ParseFloat(e.Point[:i], 64)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("cannot parse %q as latitude: %v", e.Point[:i], err)
|
||||
}
|
||||
long, err = strconv.ParseFloat(e.Point[i+1:], 64)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("cannot parse %q as longitude: %v", e.Point[i+1:], err)
|
||||
}
|
||||
}
|
||||
if e.Point != "" && lat == 0 && long == 0 {
|
||||
return p, fmt.Errorf("point=%q but couldn't parse it as lat/long", e.Point)
|
||||
}
|
||||
p = Photo{
|
||||
ID: e.ID,
|
||||
Exif: e.Exif,
|
||||
Summary: e.Summary,
|
||||
Title: e.Title,
|
||||
Location: e.Location,
|
||||
Published: e.Published,
|
||||
Updated: e.Updated,
|
||||
Latitude: lat,
|
||||
Longitude: long,
|
||||
}
|
||||
if e.Media != nil {
|
||||
p.Keywords = strings.Split(e.Media.Keywords, ",")
|
||||
p.Description = e.Media.Description
|
||||
if mc, ok := e.Media.bestContent(); ok {
|
||||
p.URL, p.Type = mc.URL, mc.Type
|
||||
}
|
||||
if p.Title == "" {
|
||||
p.Title = e.Media.Title
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (m *Media) bestContent() (ret MediaContent, ok bool) {
|
||||
// Find largest non-Flash video.
|
||||
var bestPixels int64
|
||||
for _, mc := range m.Content {
|
||||
thisPixels := int64(mc.Width) * int64(mc.Height)
|
||||
if mc.Medium == "video" && mc.Type != "application/x-shockwave-flash" && thisPixels > bestPixels {
|
||||
ret = mc
|
||||
ok = true
|
||||
bestPixels = thisPixels
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Else, just find largest anything.
|
||||
bestPixels = 0
|
||||
for _, mc := range m.Content {
|
||||
thisPixels := int64(mc.Width) * int64(mc.Height)
|
||||
if thisPixels > bestPixels {
|
||||
ret = mc
|
||||
ok = true
|
||||
bestPixels = thisPixels
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func downloadAndParse(client *http.Client, url string) (*Atom, error) {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:exif="http://schemas.google.com/photos/exif/2007" xmlns:gphoto="http://schemas.google.com/photos/2007" xmlns:media="http://search.yahoo.com/mrss/" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss">
|
||||
<id>https://picasaweb.google.com/data/feed/api/user/default/albumid/6040139514831220113</id>
|
||||
<updated>2014-07-28T23:07:15.698Z</updated>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#album"/>
|
||||
<title type="text">Biking with Blake</title>
|
||||
<subtitle type="text">Description is biking up San Bruno mountain.
|
||||
|
||||
And a newline.</subtitle>
|
||||
<rights type="text">protected</rights>
|
||||
<icon>https://lh4.googleusercontent.com/-VSf28XLm47g/U9Li4v9QrZE/AAAAAAAAAD0/Zkcd4B_xKl8/s160-c/BikingWithBlake.jpg</icon>
|
||||
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113"/>
|
||||
<link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113"/>
|
||||
<link rel="http://schemas.google.com/g/2005#resumable-create-media" type="application/atom+xml" href="https://picasaweb.google.com/data/upload/resumable/media/create-session/feed/api/user/114403741484702971746/albumid/6040139514831220113"/>
|
||||
<link rel="alternate" type="text/html" href="https://picasaweb.google.com/114403741484702971746/BikingWithBlake"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#slideshow" type="application/x-shockwave-flash" href="https://photos.gstatic.com/media/slideshow.swf?host=picasaweb.google.com&RGB=0x000000&feed=https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113?alt%3Drss"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#report" type="text/html" href="https://picasaweb.google.com/lh/reportAbuse?uname=114403741484702971746&aid=6040139514831220113"/>
|
||||
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113/acl"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113?start-index=1&max-results=1000&imgmax=d"/>
|
||||
<author>
|
||||
<name>Gast Erson</name>
|
||||
<uri>https://picasaweb.google.com/114403741484702971746</uri>
|
||||
</author>
|
||||
<generator version="1.00" uri="http://picasaweb.google.com/">Picasaweb</generator>
|
||||
<openSearch:totalResults>3</openSearch:totalResults>
|
||||
<openSearch:startIndex>1</openSearch:startIndex>
|
||||
<openSearch:itemsPerPage>1000</openSearch:itemsPerPage>
|
||||
<gphoto:id>6040139514831220113</gphoto:id>
|
||||
<gphoto:name>BikingWithBlake</gphoto:name>
|
||||
<gphoto:location>San Bruno Mt, CA</gphoto:location>
|
||||
<gphoto:access>protected</gphoto:access>
|
||||
<gphoto:timestamp>1406012400000</gphoto:timestamp>
|
||||
<gphoto:numphotos>3</gphoto:numphotos>
|
||||
<gphoto:numphotosremaining>1997</gphoto:numphotosremaining>
|
||||
<gphoto:bytesUsed>4037418</gphoto:bytesUsed>
|
||||
<gphoto:user>114403741484702971746</gphoto:user>
|
||||
<gphoto:nickname>Gast Erson</gphoto:nickname>
|
||||
<gphoto:allowPrints>true</gphoto:allowPrints>
|
||||
<gphoto:allowDownloads>true</gphoto:allowDownloads>
|
||||
<entry>
|
||||
<id>https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040139511962430354</id>
|
||||
<published>2014-07-25T23:06:10.000Z</published>
|
||||
<updated>2014-07-25T23:06:14.015Z</updated>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo"/>
|
||||
<title type="text">fail.png</title>
|
||||
<summary type="text"/>
|
||||
<content type="image/png" src="https://lh3.googleusercontent.com/-uzJVjaTng8o/U9Li4lRSa5I/AAAAAAAAABM/qHJS4rukdqM/I/fail.png"/>
|
||||
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040139511962430354"/>
|
||||
<link rel="alternate" type="text/html" href="https://picasaweb.google.com/114403741484702971746/BikingWithBlake#6040139511962430354"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#canonical" type="text/html" href="https://picasaweb.google.com/lh/photo/A_fL0dC3Fnx00P-QifpDE9MTjNZETYmyPJy0liipFm0"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040139511962430354"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040139511962430354/3"/>
|
||||
<link rel="edit-media" type="image/jpeg" href="https://picasaweb.google.com/data/media/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040139511962430354/3"/>
|
||||
<link rel="media-edit" type="image/jpeg" href="https://picasaweb.google.com/data/media/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040139511962430354/3"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#report" type="text/html" href="https://picasaweb.google.com/lh/reportAbuse?uname=114403741484702971746&aid=6040139514831220113&iid=6040139511962430354"/>
|
||||
<gphoto:id>6040139511962430354</gphoto:id>
|
||||
<gphoto:version>3</gphoto:version>
|
||||
<gphoto:position>-1.0</gphoto:position>
|
||||
<gphoto:albumid>6040139514831220113</gphoto:albumid>
|
||||
<gphoto:access>only_you</gphoto:access>
|
||||
<gphoto:width>922</gphoto:width>
|
||||
<gphoto:height>392</gphoto:height>
|
||||
<gphoto:size>58730</gphoto:size>
|
||||
<gphoto:client>es-upload-highlights</gphoto:client>
|
||||
<gphoto:checksum/>
|
||||
<gphoto:timestamp>1406329570000</gphoto:timestamp>
|
||||
<gphoto:imageVersion>19</gphoto:imageVersion>
|
||||
<gphoto:commentingEnabled>true</gphoto:commentingEnabled>
|
||||
<gphoto:commentCount>0</gphoto:commentCount>
|
||||
<gphoto:streamId>shared_group_6040139511962430354</gphoto:streamId>
|
||||
<gphoto:license id="0" name="All Rights Reserved" url="">ALL_RIGHTS_RESERVED</gphoto:license>
|
||||
<gphoto:shapes faces="done"/>
|
||||
<exif:tags>
|
||||
<exif:imageUniqueID>600da24a1bc3ddb90000000000000000</exif:imageUniqueID>
|
||||
</exif:tags>
|
||||
<media:group>
|
||||
<media:content url="https://lh3.googleusercontent.com/-uzJVjaTng8o/U9Li4lRSa5I/AAAAAAAAABM/qHJS4rukdqM/I/fail.png" height="392" width="922" type="image/png" medium="image"/>
|
||||
<media:credit>Gast Erson</media:credit>
|
||||
<media:description type="plain"/>
|
||||
<media:keywords/>
|
||||
<media:thumbnail url="https://lh3.googleusercontent.com/-uzJVjaTng8o/U9Li4lRSa5I/AAAAAAAAABM/CmypwuJHOQo/s72/fail.png" height="31" width="72"/>
|
||||
<media:thumbnail url="https://lh3.googleusercontent.com/-uzJVjaTng8o/U9Li4lRSa5I/AAAAAAAAABM/CmypwuJHOQo/s144/fail.png" height="62" width="144"/>
|
||||
<media:thumbnail url="https://lh3.googleusercontent.com/-uzJVjaTng8o/U9Li4lRSa5I/AAAAAAAAABM/CmypwuJHOQo/s288/fail.png" height="123" width="288"/>
|
||||
<media:title type="plain">fail.png</media:title>
|
||||
</media:group>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040140028386335042</id>
|
||||
<published>2014-07-25T23:08:10.000Z</published>
|
||||
<updated>2014-07-28T23:07:15.698Z</updated>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo"/>
|
||||
<title type="text">IMG_2034.JPG</title>
|
||||
<summary type="text">This is a caption</summary>
|
||||
<content type="image/jpeg" src="https://lh6.googleusercontent.com/-e8FSPDDeev8/U9LjWpGV2UI/AAAAAAAAAD0/CsA9NdVToBo/I/IMG_2034.JPG"/>
|
||||
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040140028386335042"/>
|
||||
<link rel="alternate" type="text/html" href="https://picasaweb.google.com/114403741484702971746/BikingWithBlake#6040140028386335042"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#canonical" type="text/html" href="https://picasaweb.google.com/lh/photo/m-tEQgw4HKGy-gNDTkIYudMTjNZETYmyPJy0liipFm0"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040140028386335042"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040140028386335042/16"/>
|
||||
<link rel="edit-media" type="image/jpeg" href="https://picasaweb.google.com/data/media/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040140028386335042/16"/>
|
||||
<link rel="media-edit" type="image/jpeg" href="https://picasaweb.google.com/data/media/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6040140028386335042/16"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#report" type="text/html" href="https://picasaweb.google.com/lh/reportAbuse?uname=114403741484702971746&aid=6040139514831220113&iid=6040140028386335042"/>
|
||||
<gphoto:id>6040140028386335042</gphoto:id>
|
||||
<gphoto:version>16</gphoto:version>
|
||||
<gphoto:position>0.0</gphoto:position>
|
||||
<gphoto:albumid>6040139514831220113</gphoto:albumid>
|
||||
<gphoto:access>only_you</gphoto:access>
|
||||
<gphoto:width>1183</gphoto:width>
|
||||
<gphoto:height>872</gphoto:height>
|
||||
<gphoto:size>689067</gphoto:size>
|
||||
<gphoto:client>es-pc-add-photos</gphoto:client>
|
||||
<gphoto:checksum/>
|
||||
<gphoto:timestamp>1406256485000</gphoto:timestamp>
|
||||
<gphoto:imageVersion>61</gphoto:imageVersion>
|
||||
<gphoto:commentingEnabled>true</gphoto:commentingEnabled>
|
||||
<gphoto:commentCount>1</gphoto:commentCount>
|
||||
<gphoto:streamId>shared_group_6040140028386335042</gphoto:streamId>
|
||||
<gphoto:license id="0" name="All Rights Reserved" url="">ALL_RIGHTS_RESERVED</gphoto:license>
|
||||
<gphoto:shapes faces="done"/>
|
||||
<exif:tags>
|
||||
<exif:fstop>2.2</exif:fstop>
|
||||
<exif:make>Apple</exif:make>
|
||||
<exif:model>iPhone 5s</exif:model>
|
||||
<exif:exposure>0.001242236</exif:exposure>
|
||||
<exif:flash>false</exif:flash>
|
||||
<exif:focallength>4.12</exif:focallength>
|
||||
<exif:iso>32</exif:iso>
|
||||
<exif:time>1406231285000</exif:time>
|
||||
<exif:imageUniqueID>6e37fb5bf62bde9e0000000000000000</exif:imageUniqueID>
|
||||
</exif:tags>
|
||||
<media:group>
|
||||
<media:content url="https://lh6.googleusercontent.com/-e8FSPDDeev8/U9LjWpGV2UI/AAAAAAAAAD0/CsA9NdVToBo/I/IMG_2034.JPG" height="872" width="1183" type="image/jpeg" medium="image"/>
|
||||
<media:credit>Gast Erson</media:credit>
|
||||
<media:description type="plain">This is a caption</media:description>
|
||||
<media:keywords/>
|
||||
<media:thumbnail url="https://lh6.googleusercontent.com/-e8FSPDDeev8/U9LjWpGV2UI/AAAAAAAAAD0/HsMxroJpDMw/s72/IMG_2034.JPG" height="54" width="72"/>
|
||||
<media:thumbnail url="https://lh6.googleusercontent.com/-e8FSPDDeev8/U9LjWpGV2UI/AAAAAAAAAD0/HsMxroJpDMw/s144/IMG_2034.JPG" height="107" width="144"/>
|
||||
<media:thumbnail url="https://lh6.googleusercontent.com/-e8FSPDDeev8/U9LjWpGV2UI/AAAAAAAAAD0/HsMxroJpDMw/s288/IMG_2034.JPG" height="213" width="288"/>
|
||||
<media:title type="plain">IMG_2034.JPG</media:title>
|
||||
</media:group>
|
||||
<georss:where>
|
||||
<gml:Point>
|
||||
<gml:pos>37.6955972 -122.4339361</gml:pos>
|
||||
</gml:Point>
|
||||
</georss:where>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6041225428268790466</id>
|
||||
<published>2014-07-28T21:20:04.000Z</published>
|
||||
<updated>2014-07-28T22:20:42.270Z</updated>
|
||||
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo"/>
|
||||
<title type="text">VID_20140728_141919.mp4</title>
|
||||
<summary type="text"/>
|
||||
<content type="image/gif" src="https://lh3.googleusercontent.com/-STi02l3-QBE/U9a-hOwEssI/AAAAAAAAAC0/ljSrrqKjShE/I/VID_20140728_141919.gif"/>
|
||||
<link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://picasaweb.google.com/data/feed/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6041225428268790466"/>
|
||||
<link rel="alternate" type="text/html" href="https://picasaweb.google.com/114403741484702971746/BikingWithBlake#6041225428268790466"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#canonical" type="text/html" href="https://picasaweb.google.com/lh/photo/Cf4wdphhOQS3yBMxfmeZZNMTjNZETYmyPJy0liipFm0"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6041225428268790466"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://picasaweb.google.com/data/entry/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6041225428268790466/9"/>
|
||||
<link rel="edit-media" type="image/jpeg" href="https://picasaweb.google.com/data/media/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6041225428268790466/9"/>
|
||||
<link rel="media-edit" type="image/jpeg" href="https://picasaweb.google.com/data/media/api/user/114403741484702971746/albumid/6040139514831220113/photoid/6041225428268790466/9"/>
|
||||
<link rel="http://schemas.google.com/photos/2007#report" type="text/html" href="https://picasaweb.google.com/lh/reportAbuse?uname=114403741484702971746&aid=6040139514831220113&iid=6041225428268790466"/>
|
||||
<gphoto:id>6041225428268790466</gphoto:id>
|
||||
<gphoto:version>9</gphoto:version>
|
||||
<gphoto:position>1.0</gphoto:position>
|
||||
<gphoto:albumid>6040139514831220113</gphoto:albumid>
|
||||
<gphoto:access>only_you</gphoto:access>
|
||||
<gphoto:videostatus>final</gphoto:videostatus>
|
||||
<gphoto:originalvideo width="1920" height="1080" type="MOV" duration="1" channels="1" samplingrate="48.0" videoCodec="H264" audioCodec="AAC" fps="29.833334"/>
|
||||
<gphoto:width>854</gphoto:width>
|
||||
<gphoto:height>480</gphoto:height>
|
||||
<gphoto:size>3289621</gphoto:size>
|
||||
<gphoto:client>pwa</gphoto:client>
|
||||
<gphoto:checksum/>
|
||||
<gphoto:timestamp>1406607562000</gphoto:timestamp>
|
||||
<gphoto:imageVersion>45</gphoto:imageVersion>
|
||||
<gphoto:commentingEnabled>true</gphoto:commentingEnabled>
|
||||
<gphoto:commentCount>0</gphoto:commentCount>
|
||||
<gphoto:streamId>shared_group_6041225428268790466</gphoto:streamId>
|
||||
<gphoto:license id="0" name="All Rights Reserved" url="">ALL_RIGHTS_RESERVED</gphoto:license>
|
||||
<gphoto:shapes faces="done"/>
|
||||
<exif:tags>
|
||||
<exif:imageUniqueID>78d317eb33e596180000000000000000</exif:imageUniqueID>
|
||||
</exif:tags>
|
||||
<media:group>
|
||||
<media:content url="https://lh3.googleusercontent.com/-STi02l3-QBE/U9a-hOwEssI/AAAAAAAAAC0/ljSrrqKjShE/I/VID_20140728_141919.gif" height="480" width="854" type="image/gif" medium="image"/>
|
||||
<media:content url="https://redirector.googlevideo.com/videoplayback?requiressl=yes&shardbypass=yes&cmbypass=yes&id=bd73dcba2da276ec&itag=18&source=picasa&cmo=secure_transport%3Dyes&ip=0.0.0.0&ipbits=0&expire=1409241526&sparams=requiressl,shardbypass,cmbypass,id,itag,source,ip,ipbits,expire&signature=83B789FDE8A4B67C6CF8C3734274DC5EEA7048DD.D62C52CA7E0D523E98828902D7D236F95AD6F65F&key=lh1" height="360" width="640" type="video/mpeg4" medium="video"/>
|
||||
<media:content url="https://redirector.googlevideo.com/videoplayback?requiressl=yes&shardbypass=yes&cmbypass=yes&id=bd73dcba2da276ec&itag=34&source=picasa&cmo=secure_transport%3Dyes&ip=0.0.0.0&ipbits=0&expire=1409241526&sparams=requiressl,shardbypass,cmbypass,id,itag,source,ip,ipbits,expire&signature=217D84462A42D4CB88B09F75B047C68F4241A9DF.B98B88E4A5A125F4A3796C22CF494CF1154AF38C&key=lh1" height="360" width="640" type="application/x-shockwave-flash" medium="video"/>
|
||||
<media:content url="https://redirector.googlevideo.com/videoplayback?requiressl=yes&shardbypass=yes&cmbypass=yes&id=bd73dcba2da276ec&itag=35&source=picasa&cmo=secure_transport%3Dyes&ip=0.0.0.0&ipbits=0&expire=1409241526&sparams=requiressl,shardbypass,cmbypass,id,itag,source,ip,ipbits,expire&signature=10070B78812CE54BCE0528FAE5453D1BF54959E5.2A1C9043CED774A59854E56556893A4891777D75&key=lh1" height="480" width="854" type="application/x-shockwave-flash" medium="video"/>
|
||||
<media:content url="https://redirector.googlevideo.com/videoplayback?requiressl=yes&shardbypass=yes&cmbypass=yes&id=bd73dcba2da276ec&itag=22&source=picasa&cmo=secure_transport%3Dyes&ip=0.0.0.0&ipbits=0&expire=1409241526&sparams=requiressl,shardbypass,cmbypass,id,itag,source,ip,ipbits,expire&signature=3D7F7A631ADF6B1A8220E3571E60AF6DF77274AE.DAD9E2C950E278F57653E2AE93F36F8D6235FDBC&key=lh1" height="720" width="1280" type="video/mpeg4" medium="video"/>
|
||||
<media:content url="https://foo.googlevideo.com/bar.mp4" height="1080" width="1920" type="video/mpeg4" medium="video"/>
|
||||
<media:credit>Gast Erson</media:credit>
|
||||
<media:description type="plain"/>
|
||||
<media:keywords>keyboard, stuff</media:keywords>
|
||||
<media:thumbnail url="https://lh3.googleusercontent.com/-STi02l3-QBE/U9a-hOwEssI/AAAAAAAAAC0/jYJqb4T2I4E/s72/VID_20140728_141919.png" height="41" width="72"/>
|
||||
<media:thumbnail url="https://lh3.googleusercontent.com/-STi02l3-QBE/U9a-hOwEssI/AAAAAAAAAC0/jYJqb4T2I4E/s144/VID_20140728_141919.png" height="81" width="144"/>
|
||||
<media:thumbnail url="https://lh3.googleusercontent.com/-STi02l3-QBE/U9a-hOwEssI/AAAAAAAAAC0/jYJqb4T2I4E/s288/VID_20140728_141919.png" height="162" width="288"/>
|
||||
<media:title type="plain">VID_20140728_141919.mp4</media:title>
|
||||
</media:group>
|
||||
<georss:where>
|
||||
<gml:Point>
|
||||
<gml:pos>37.7447 -122.434</gml:pos>
|
||||
</gml:Point>
|
||||
</georss:where>
|
||||
</entry>
|
||||
</feed>
|
Loading…
Reference in New Issue