An elegant way to solve a GoogleReader task?

Asked by mindblaster

sorry I'm totally lost in the Phyton syntax and tried for some hours to to find a way to solve an easy Google Reader task, but have not enough experience to decide what way to go, and would be really glad for some advice what to do next:

The problem should be easy:

  I have in Google Reader a site with "starred" articles which i like to check for:
       if they are also "liked" (in most cases) and
       if the are "shared" (reader was not able to update some for this)
in both cases if the symbol is not there for "sharing" or "liking", i like to add it.
-then repeat this with the next article and so on...

in reality an article looks like

          (star-symbol)

          x person like it (with the not checked like-symbol) (unclickable)
                 article - in some cases longer than the screen
          (star-symbol) remove star (liked-symbol) unlike (share-Symbol) unshare

and as far as I see there are two ways to solve this:
first i need to search for the bottom of the article with the symbols
    switchApp("Google Chrome.app")
    while not find(a image of the active starred article bottom line ):
        click(scrolldownarrow)

and then the elegant way should be to search for the whole symbol bar on the bottom of the active article and then click selectively the symbols i like to change (or if it's already set just click on next article or "n")
-for someone how knows Phyton this should be a breeze, but i must admit that i gave up after some hours of syntax errors:

so i tried the basic way - that would be to make an image of every possible state of the symbol bar at the bottom of the active article and then press for every possibility the right symbols.
If I have 3 symbols and the first is always active, it's a breeze:
                      starred liked unshared
                       starred unliked shared
                       starred unshared unliked

and starred liked shared

But I don't even get this one right (not to speak of the first one)

a "if then/else" Spaghetti code with the different image permutations

and for the end a "click next item" "n"

but i don't even have a clue how to end the code, when there are no more items left...

I know it's a little much to ask, but if someone can give me a little hint how to solve this, this would be great :)

Best Regards,
adrian

Question information

Language:
English Edit question
Status:
Answered
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

Interesting.

I'm using NetNewsWire, so I have a Google Reader in the background. Just checked, what you are telling.

As a start, there should be a page open, where only the list of marked items (yellow star) is shown (no sidebars!).
All items should be un-collapsed.

The strategie for this workflow could be, to use the fact, that only one entry on a page is "active" ( = has e dark blue border) and then use key arrow down to get to the footer of the current entry, if the entry exceeds a page.
To get the next entry active, we use the button "next ..." at the bottom of the screen.
To end the loop, we have to check for a situation, that only comes up, when clicking "next ..." and nothing happens (may be tricky).
The browser window should be full screen.

basically we need to pictures:
- upper left corner with the yellow star and part of the blue border to identify the active entry
- lower left corner with the yellow star and the text "remove mark" or so (sorry, my reader is german)

When you test this, you will learn, that also the lighter blue may be found, but with a lower similarity. So we use a Pattern instead, to define a higher similarity.

so we can do the following outer loop:

upLeft = Pattern(<star + border>).similar(0.9)
lowLeft = Pattern(<star + text + border>).similar(0.9)
next = find(<picture of button "next ..." at the bottom>) # we store the match, since the button will be there all the time

theEnd = False

while not theEnd:
    up = find(upLeft)
    # here we can do something with the head of the entry
    low = find(lowLeft)
    # now we know, the footer is there and we can check and click in the footer
    click(next)
    # check wether there are more entries
    if no_more_entries:
       theEnd = true or break

When you use 0.9.9 (recommended) every time a find() does not succeed, the script will stop with a find failed exception.

may be this helps you to get on the road. First just try to get thru the list, then the other details.

I will come back later on with a solution for "entry is longer than one page".

Have fun.

Revision history for this message
RaiMan (raimund-hocke) said :
#2

Now the solution for the long entries (whole script, I changed the loop)

When you are new to Python, mind the indentation (e.g. 3 blanks for every indentation level). This is the way how in Python you build blocks of statements.

upLeft = Pattern(<star + border>).similar(0.9)
lowLeft = Pattern(<star + text + border>).similar(0.9)
next = find(<picture of button "next ..." at the bottom>) # we store the match, since the button will be there all the time

while True:
   up = find(upLeft)
   # here we can do something with the head of the entry

   while True:
      try:
         low = wait(lowLeft, 100)
         break
      except FindFailed:
         type(Key.DOWN)

   # now we know, the footer is there and we can check and click in the footer
   click(next)
   # check wether there are more entries
   if no_more_entries:
      break

explanation:
we try: to find the footer (I use wait, so I can limit the search time). If not found, we get a FindFailed exception, that we catch (except FindFailed:) and scroll down a little.
If found, the loop is stopped, since we come to the break statement.

Revision history for this message
RaiMan (raimund-hocke) said :
#3

Now handling the footer:
We use the same approach (the script has to continue in either case):
unLike = Pattern(<pic of unlike symbol + text + the blue border below>).similar(0.9)
weLike = Pattern(<pic of like symbol + text + the blue border below>).similar(0.9)

try:
   find(unLike)
except FindFailed:
   # now we know, that we did not like the entry until now and we click it
   click(weLike)

----- whole script until now:
upLeft = Pattern(<star + border>).similar(0.9)
lowLeft = Pattern(<star + text + border>).similar(0.9)
unLike = Pattern(<unlike symbol + text + blue border>).similar(0.9)
weLike = Pattern(<like symbol + text + blue border>).similar(0.9)
next = find(<picture of button "next ..." at the bottom>) # we store the match, since the button will be there all the time
cnt = 0

while True:
   up = find(upLeft)
   # here we can do something with the head of the entry

   while True:
      try:
         low = wait(lowLeft, 100)
         break
      except FindFailed:
         type(Key.DOWN)

      # we work with the footer
      try:
         wait(unLike, 1) # we use wait to speed up the workflow
      except FindFailed:
         # now we know, that we did not like the entry until now and we click it
         click(weLike)

   click(next)

   # check wether there are more entries
   if no_more_entries:
      break

   # this could be the hand brake
   cnt += 1

If at any time, you get the impression, that the script is in an infinite loop or you want to stop it, try alt-shift-c or click the minimize button of the browser window (next find() will fail and end your script).

May be this is enough, to get you to what you want. May be you find a solution to end the loop yourself.
At any time you can paste your script and write down your ideas, I will try to help you.

Revision history for this message
RaiMan (raimund-hocke) said :
#4

Sorry, somehow I saved the comment to early:

   # this could be the hand brake
   cnt += 1
   if cnt > 50: # stop the loop after 50 cycles or whatever
      break

Can you help with this problem?

Provide an answer of your own, or ask mindblaster for more information if necessary.

To post a message you must log in.