pull/3/merge
Daniel Lauzon 4 years ago committed by GitHub
commit fb8fac3362
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,7 +19,6 @@ limitations under the License.
package main package main
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"flag" "flag"
@ -34,7 +33,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/input" "github.com/chromedp/cdproto/input"
"github.com/chromedp/cdproto/page" "github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp" "github.com/chromedp/chromedp"
@ -263,90 +261,61 @@ func (s *Session) firstNav(ctx context.Context) error {
return err return err
} }
if err := navToLast(ctx); err != nil {
return err
}
return nil return nil
} }
// navToEnd waits for the page to be ready to receive scroll key events, by // navToEnd selects the last item in the page
// trying to select an item with the right arrow key, and then scrolls down to the // by repeatedly advancing the selected item with
// end of the page, i.e. to the oldest items. // - kb.ArrowRight (which causes an initial selection, and/or advances it by one)
// - kb.End which scrolls to the end of the page, and advances the selected item.
// Note timing is important, because when the kb.End causes significant scrolling,
// the active element become undefined for a certain time, in that case, we
// get an error (ignore), sleep, and retry.
// The termnation criteria is that the selected item (document.activeElement.href)
// is stable for >2 iterations
func navToEnd(ctx context.Context) error { func navToEnd(ctx context.Context) error {
// wait for page to be loaded, i.e. that we can make an element active by using var prev, active string
// the right arrow key. lastRepeated := 0
for { for {
chromedp.KeyEvent(kb.ArrowRight).Do(ctx) chromedp.KeyEvent(kb.ArrowRight).Do(ctx)
chromedp.KeyEvent(kb.End).Do(ctx)
time.Sleep(tick) time.Sleep(tick)
var ids []cdp.NodeID
if err := chromedp.Run(ctx, if err := chromedp.Evaluate(`document.activeElement.href`, &active).Do(ctx); err != nil {
chromedp.NodeIDs(`document.activeElement`, &ids, chromedp.ByJSPath)); err != nil { // This extra sleep is important: after the kb.End,
return err // it sometimes takes a while for the scrolled page to be in a state
// which allows the next kb.ArrowRight to take effect and actually select
// the next element at the new scroll position.
time.Sleep(tick)
continue // ignore this error: no active element, or active element has no href
} }
if len(ids) > 0 { if active == prev {
if *verboseFlag { lastRepeated++
log.Printf("We are ready, because element %v is selected", ids[0]) } else {
} lastRepeated = 0
break
} }
time.Sleep(tick) if *verboseFlag {
} log.Printf("Active element %s was seen %d times", active, lastRepeated+1)
// try jumping to the end of the page. detect we are there and have stopped
// moving when two consecutive screenshots are identical.
var previousScr, scr []byte
for {
chromedp.KeyEvent(kb.PageDown).Do(ctx)
chromedp.KeyEvent(kb.End).Do(ctx)
chromedp.CaptureScreenshot(&scr).Do(ctx)
if previousScr == nil {
previousScr = scr
continue
} }
if bytes.Equal(previousScr, scr) { if lastRepeated > 2 {
break break
} }
previousScr = scr prev = active
time.Sleep(tick)
} }
if *verboseFlag { chromedp.KeyEvent("\n").Do(ctx)
log.Printf("Successfully jumped to the end") time.Sleep(tick)
var location string
if err := chromedp.Location(&location).Do(ctx); err != nil {
return err
} }
return nil if active == location {
} if *verboseFlag {
log.Printf("Successfully jumped to the end: %s", location)
// navToLast sends the "\n" event until we detect that an item is loaded as a
// new page. It then sends the right arrow key event until we've reached the very
// last item.
func navToLast(ctx context.Context) error {
var location, prevLocation string
ready := false
for {
chromedp.KeyEvent(kb.ArrowRight).Do(ctx)
time.Sleep(tick)
if !ready {
chromedp.KeyEvent("\n").Do(ctx)
time.Sleep(tick)
}
if err := chromedp.Location(&location).Do(ctx); err != nil {
return err
}
if !ready {
if location != "https://photos.google.com/" {
ready = true
log.Printf("Nav to the end sequence is started because location is %v", location)
}
continue
}
if location == prevLocation {
break
} }
prevLocation = location
} }
return nil return nil
} }
@ -579,6 +548,9 @@ func (s *Session) navN(N int) func(context.Context) error {
return err return err
} }
if location == prevLocation { if location == prevLocation {
if *verboseFlag {
log.Printf("Terminating because we stopped advancing: %s", prevLocation)
}
break break
} }
prevLocation = location prevLocation = location
@ -591,6 +563,9 @@ func (s *Session) navN(N int) func(context.Context) error {
} }
n++ n++
if N > 0 && n >= N { if N > 0 && n >= N {
if *verboseFlag {
log.Printf("Terminating because desired number of items (%d) was reached", n)
}
break break
} }

Loading…
Cancel
Save