internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: internetarchive/openlibrary

Issue:
Allow deletion of (incorrect) contributors
It seems to be impossible to delete contributors from Editions. When I edit an Edition, click the [x] next to a contributor, it dissappears. But after saving the record, all deleted contributors are still there.
Of course I have only tried to delete bogus contributors, like the one on http://openlibrary.org/books/OL25114356M/Book_of_Pure_Logic (it is hard to say what was meant here, my best guess is "the author is also designer, editor and publisher of this book"). But also trying to correct typos I made myself is not possible.



Discussion:
@mekarpeles could this be a first timer issue for a feature that we'd like to have under Hacktoberfest?
This is still a bug. Specifically when I try to edit only the contributors in the above URL, my change is not saved. 

@mekarpeles defaulting to assigning you per our slack discussion
I was able to reproduce this locally.
I noticed that if there are more than one (not including author) contributors you can remove all but one of them and it will save successfully.

I noticed if I set the role/name to blank in the http request it will delete it.

So I think there are two ways to go about this:
1. Make the frontend send the contributors as blank instead of not sending them at all when deleting.
2. Do something on backend to handle the case of no contributors being sent and make sure that causes contributors to be deleted.


I think 1 would be a reasonable approach but may result in code that's a little ugly.

Does anyone know how I would go about doing 2? 

Resolving patch:
diff --git a/openlibrary/plugins/upstream/addbook.py b/openlibrary/plugins/upstream/addbook.py
--- a/openlibrary/plugins/upstream/addbook.py
+++ b/openlibrary/plugins/upstream/addbook.py
@@ -566,6 +566,9 @@ def save(self, formdata):
                 edition_data.translation_of = None
                 edition_data.translated_from = None
 
+            if 'contributors' not in edition_data:
+                self.edition.contributors = []
+
             self.edition.update(edition_data)
             saveutil.save(self.edition)
 


Test patch:
Repository: internetarchive/openlibrary

Issue:
Unable to login using ia credentials
<!-- What problem are we solving? What does the experience look like today? What are the symptoms? -->
OL client uses the IA login method to log in and retrieve the session. It makes a call to `/account/login` with a `access` and a `secret` in the JSON body. These are sourced from `ia.configure()`. I think this used to work before since a lot of scripts were logging in and doing admin ops. But looks like now, the API endpoint now throws a 400 with a response body that says `username`.

Timeline lines up with https://github.com/internetarchive/openlibrary/releases/tag/deploy-2021-10-26

[slack conversation reference](https://internetarchive.slack.com/archives/C0ETZV72L/p1635495329042000)

### Stakeholders
<!-- @ tag stakeholders of this bug -->
@cdrini 


Discussion:

Resolving patch:
diff --git a/openlibrary/plugins/openlibrary/code.py b/openlibrary/plugins/openlibrary/code.py
--- a/openlibrary/plugins/openlibrary/code.py
+++ b/openlibrary/plugins/openlibrary/code.py
@@ -18,9 +18,6 @@
 import infogami
 
 # make sure infogami.config.features is set
-from openlibrary.book_providers import get_book_provider, get_book_provider_by_name, \
-    get_cover_url
-
 if not hasattr(infogami.config, 'features'):
     infogami.config.features = []
 
@@ -931,6 +928,14 @@ def is_bot():
 
 
 def setup_template_globals():
+    # must be imported here, otherwise silently messes up infogami's import execution
+    # order, resulting in random errors like the the /account/login.json endpoint
+    # defined in accounts.py being ignored, and using the infogami endpoint instead.
+    from openlibrary.book_providers import (
+        get_book_provider,
+        get_book_provider_by_name,
+        get_cover_url,
+    )
     web.template.Template.globals.update({
         'next': next,
         'sorted': sorted,


Test patch:
Repository: internetarchive/openlibrary

Issue:
Improvements + Fixes to work /delete endpoint
In preparation of some bulk notebook deletes, need some fixes to the delete API!

- [x] Expand access to also include bot accounts
- [x] Deleting the works only deletes the first 20 editions! ❗ 

### Stakeholders

@cdrini 


Discussion:

Resolving patch:
diff --git a/openlibrary/plugins/openlibrary/api.py b/openlibrary/plugins/openlibrary/api.py
--- a/openlibrary/plugins/openlibrary/api.py
+++ b/openlibrary/plugins/openlibrary/api.py
@@ -15,6 +15,7 @@
 from infogami.plugins.api.code import jsonapi
 from infogami.utils.view import add_flash_message
 from openlibrary import accounts
+from openlibrary.plugins.openlibrary.code import can_write
 from openlibrary.utils.isbn import isbn_10_to_isbn_13, normalize_isbn
 from openlibrary.utils import extract_numeric_id_from_olid
 from openlibrary.plugins.worksearch.subjects import get_subject
@@ -493,12 +494,24 @@ class work_delete(delegate.page):
     path = r"/works/(OL\d+W)/[^/]+/delete"
 
     def get_editions_of_work(self, work: Work) -> list[dict]:
-        keys: list = web.ctx.site.things({"type": "/type/edition", "works": work.key})
+        limit = 1_000  # This is the max limit of the things function
+        keys: list = web.ctx.site.things({
+            "type": "/type/edition",
+            "works": work.key,
+            "limit": limit
+        })
+        if len(keys) == limit:
+            raise web.HTTPError(
+                '400 Bad Request',
+                data=json.dumps({
+                    'error': f'API can only delete {limit} editions per work',
+                }),
+                headers={"Content-Type": "application/json"},
+            )
         return web.ctx.site.get_many(keys, raw=True)
 
     def POST(self, work_id: str):
-        user = accounts.get_current_user()
-        if not (user and (user.is_admin() or user.is_librarian())):
+        if not can_write():
             return web.HTTPError('403 Forbidden')
 
         web_input = web.input(comment=None)


Test patch:
Repository: internetarchive/openlibrary

Issue:
Work search - Sort by first published displays work with no publication date first
<!-- What problem are we solving? What does the experience look like today? What are the symptoms? -->
When searching for a work and sorting by `First Published`, if some works match the search and have no first publication date, they appear first.
I expected to see works with known first published year first and not pages later.

### Evidence / Screenshot (if possible)
n/a

### Relevant url?
<!-- `https://openlibrary.org/...` -->
For example: https://openlibrary.org/search?q=calamity&mode=everything&sort=old

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Search for `calamity` in the search bar (https://openlibrary.org/search?q=calamity&mode=everything)
2. Sort by `First Published` (https://openlibrary.org/search?q=calamity&mode=everything&sort=old)

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual: First result is `The Mount Rushmore Calamity by Jeff Brown` with no publication date
* Expected:  `A theatre wherein be represented as wel the miseries & calamities that follow the voluptuous worldlings by Noot, Jan van der`, first published in 1569 and only displayed on page 2 of the search

### Details

- **Logged in (Y/N)?** No
- **Browser type/version?** 
- **Operating system?** 
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->
When sorting by publication date (`First Published` or `Most Recent`), works with no publication date should be the last results displayed.

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->



Discussion:

Resolving patch:
diff --git a/openlibrary/plugins/worksearch/code.py b/openlibrary/plugins/worksearch/code.py
--- a/openlibrary/plugins/worksearch/code.py
+++ b/openlibrary/plugins/worksearch/code.py
@@ -116,7 +116,7 @@
 }
 SORTS = {
     'editions': 'edition_count desc',
-    'old': 'first_publish_year asc',
+    'old': 'def(first_publish_year, 9999) asc',
     'new': 'first_publish_year desc',
     'scans': 'ia_count desc',
     # Classifications


Test patch:
Repository: internetarchive/openlibrary

Issue:
Add Star Ratings to Reading Log Page
Specifically on the "already read" page, get all the reader's ratings and shuffle them into the books they've already read. Let them vote from the private "already read" bookshelf page (careful -- there's a public reading log page too which some users have activated)


Discussion:

Resolving patch:
diff --git a/openlibrary/plugins/openlibrary/api.py b/openlibrary/plugins/openlibrary/api.py
--- a/openlibrary/plugins/openlibrary/api.py
+++ b/openlibrary/plugins/openlibrary/api.py
@@ -97,8 +97,10 @@ class ratings(delegate.page):
     def POST(self, work_id):
         """Registers new ratings for this work"""
         user = accounts.get_current_user()
-        i = web.input(edition_id=None, rating=None, redir=False)
-        key = i.edition_id if i.edition_id else ('/works/OL%sW' % work_id)
+        i = web.input(edition_id=None, rating=None, redir=False, redir_url=None, page=None)
+        key = (i.redir_url if i.redir_url else
+            i.edition_id if i.edition_id else
+            ('/works/OL%sW' % work_id))
         edition_id = (
             int(extract_numeric_id_from_olid(i.edition_id)) if i.edition_id else None
         )
@@ -131,6 +133,11 @@ def response(msg, status="success"):
             r = response('rating added')
 
         if i.redir:
+            p = h.safeint(i.page, 1)
+            query_params = f'?page={p}' if p > 1 else ''
+            if i.page:
+                raise web.seeother(f'{key}{query_params}')
+
             raise web.seeother(key)
         return r
 
diff --git a/openlibrary/plugins/upstream/account.py b/openlibrary/plugins/upstream/account.py
--- a/openlibrary/plugins/upstream/account.py
+++ b/openlibrary/plugins/upstream/account.py
@@ -741,9 +741,11 @@ class account_my_books_redirect(delegate.page):
 
     @require_login
     def GET(self, rest='loans'):
+        i = web.input(page=1)
         user = accounts.get_current_user()
         username = user.key.split('/')[-1]
-        raise web.seeother(f'/people/{username}/books/{rest}')
+        query_params = f'?page={i.page}' if h.safeint(i.page) > 1 else ''
+        raise web.seeother(f'/people/{username}/books/{rest}{query_params}')
 
 
 class account_my_books(delegate.page):


Test patch:
Repository: internetarchive/openlibrary

Issue:
Add TESTING flag for scripts/oldumps.sh given the long runtimes
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->

### Describe the problem that you'd like solved
<!-- A clear and concise description of what you want to happen. -->

See review feedback on #5892
Fixed in #5909

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

<!-- Which suggestions or requirements should be considered for how feature needs to appear or be implemented? -->

### Additional context
<!-- Add any other context or screenshots about the feature request here. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->





Discussion:

Resolving patch:
diff --git a/openlibrary/data/dump.py b/openlibrary/data/dump.py
--- a/openlibrary/data/dump.py
+++ b/openlibrary/data/dump.py
@@ -107,9 +107,12 @@ def generate_cdump(data_file, date=None):
     #   False
     #   >>> "2010-05-17T10:20:30" < "2010-05-17Z"
     #   True
+    #
+    # If scripts/oldump.sh has exported $OLDUMP_TESTING then save a lot of time by only
+    # processing a subset of the lines in data_file.
+    max_lines = 1_000_000 if os.getenv("OLDUMP_TESTING") else 0  # 0 means unlimited.
     filter = date and (lambda doc: doc["last_modified"]["value"] < date + "Z")
-
-    print_dump(read_data_file(data_file), filter=filter)
+    print_dump(read_data_file(data_file, max_lines), filter=filter)
 
 
 def sort_dump(dump_file=None, tmpdir="/tmp/", buffer_size="1G"):


Test patch:
Repository: internetarchive/openlibrary

Issue:
Reversion: author searches with wildcards fail
<!-- What problem are we solving? What does the experience look like today? What are the symptoms? -->
Wildcard asterisk fails in author name search, but works in "All" search. This used to work. 
### Evidence / Screenshot (if possible)
![A097E003-93BE-454E-8696-6BD66A64068D](https://user-images.githubusercontent.com/11435431/138561672-765afb2c-3f70-4db6-840e-d4e6f4c97ffb.png)
![22BF5133-458D-463E-B26B-DB2B43E9519C](https://user-images.githubusercontent.com/11435431/138561674-16449abc-5473-4c9c-aed4-67c4ad4db603.png)

### Relevant url?
<!-- `https://openlibrary.org/...` -->
https://openlibrary.org/search?q=Jon+kabat*&mode=everything

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Go to search bar
2. Enter a partial name ending with *
3. Select "Author" as search type
4. Run query

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual: nothing found
* Expected: list of matching authors

### Details

- **Logged in (Y/N)?** y
- **Browser type/version?** Safari or Chrome
- **Operating system?** iPadOS
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->



Discussion:
Ahhh, I think this broke in this commit: 694355826d9528629aa29f9eb403abb952afc888 when I enabled `dismax` for author queries ; should be an easy fix!

Resolving patch:
diff --git a/openlibrary/plugins/worksearch/code.py b/openlibrary/plugins/worksearch/code.py
--- a/openlibrary/plugins/worksearch/code.py
+++ b/openlibrary/plugins/worksearch/code.py
@@ -1108,7 +1108,7 @@ def get_results(self, q, offset=0, limit=100):
             'work_count',
         ]
         q = escape_colon(escape_bracket(q), valid_fields)
-        q_has_fields = ':' in q.replace(r'\:', '')
+        q_has_fields = ':' in q.replace(r'\:', '') or '*' in q
 
         d = run_solr_search(
             solr_select_url,


Test patch:
Repository: internetarchive/openlibrary

Issue:
Return book button should go to loans page not editions page
 "Return Book" workflow. when you return a book through your "My Loans" page you are redirected to the edition page of the book you just returned. is that because there is an assumption that many want to re-borrow? i'd think you would 1) remain on the "My Loans" page, 2) that book would disappear and then 3) you could possibly return others. redirecting to the page of the book you just returned seems a bit non-intuitive.

Reported by @JeffKaplan 


Discussion:
I think this can be done within the return code in plugins/upstream/borrow.py or core/lending.py?
I can work on this issue!!
I would like to work on this issue.
Can I work on this issue 
@b-thebest Sorry for the delay!  Are you still interested in working on this?
Hello! Could I work on this issue?
> @b-thebest Sorry for the delay! Are you still interested in working on this?

Yes, I am interested. Please assign this issue to me
I would like to contribute and work on this issue, is that possible? 
I am new to open source contribution and I would love to work on this issue if it can be assigned to me.
@ujjwaltwitx welcome!  Let me know if you need any help getting started.

Resolving patch:
diff --git a/openlibrary/plugins/upstream/borrow.py b/openlibrary/plugins/upstream/borrow.py
--- a/openlibrary/plugins/upstream/borrow.py
+++ b/openlibrary/plugins/upstream/borrow.py
@@ -151,7 +151,9 @@ def POST(self, key):
         if action == 'return':
             lending.s3_loan_api(edition.ocaid, s3_keys, action='return_loan')
             stats.increment('ol.loans.return')
-            raise web.seeother(edition_redirect)
+            edition.update_loan_status()
+            user.update_loan_status()
+            raise web.seeother('/account/loans')
         elif action == 'join-waitinglist':
             lending.s3_loan_api(edition.ocaid, s3_keys, action='join_waitlist')
             stats.increment('ol.loans.joinWaitlist')


Test patch:
Repository: internetarchive/openlibrary

Issue:
Add covers to standard ebooks script
Subtask of #5792 

We discovered in #5993 (Thank you @hornc !) that our import endpoint already supports covers! We just need `cover: "http://foo..."` in the json.

Now we just need to update the standard ebooks importer to include the cover in the import request.

### Related files

https://github.com/internetarchive/openlibrary/blob/master/scripts/import_standard_ebooks.py


Discussion:
Marking as P1 since it'll unblock us being able to run this thing, and get standard ebooks read links working!

Resolving patch:
diff --git a/scripts/import_standard_ebooks.py b/scripts/import_standard_ebooks.py
old mode 100644
new mode 100755
--- a/scripts/import_standard_ebooks.py
+++ b/scripts/import_standard_ebooks.py
@@ -15,7 +15,8 @@
 
 FEED_URL = 'https://standardebooks.org/opds/all'
 LAST_UPDATED_TIME = './standard_ebooks_last_updated.txt'
-
+IMAGE_REL = 'http://opds-spec.org/image'
+BASE_SE_URL = 'https://standardebooks.org'
 
 def get_feed():
     """Fetches and returns Standard Ebook's feed."""
@@ -26,7 +27,9 @@ def get_feed():
 def map_data(entry) -> dict[str, Any]:
     """Maps Standard Ebooks feed entry to an Open Library import object."""
     std_ebooks_id = entry.id.replace('https://standardebooks.org/ebooks/', '')
-    return {
+    image_uris = filter(lambda link: link.rel == IMAGE_REL, entry.links)
+
+    import_record =  {
         "title": entry.title,
         "source_records": [f"standard_ebooks:{std_ebooks_id}"],
         "publishers": [entry.publisher],
@@ -39,6 +42,11 @@ def map_data(entry) -> dict[str, Any]:
         }
     }
 
+    if image_uris:
+        import_record['cover'] = f'{BASE_SE_URL}{list(image_uris)[0]["href"]}'
+
+    return import_record
+
 
 def create_batch(records: list[dict[str, str]]) -> None:
     """Creates Standard Ebook batch import job.
@@ -162,9 +170,10 @@ def import_job(
             print(json.dumps(record))
 
     # Store timestamp for header
-    with open(LAST_UPDATED_TIME, 'w+') as f:
-        f.write(last_modified)
-        print(f'Last updated timestamp written to: {LAST_UPDATED_TIME}')
+    if not dry_run:
+        with open(LAST_UPDATED_TIME, 'w+') as f:
+            f.write(last_modified)
+            print(f'Last updated timestamp written to: {LAST_UPDATED_TIME}')
 
 
 if __name__ == '__main__':


Test patch:
Repository: internetarchive/openlibrary

Issue:
Cannot reverse deleted or merged works
When trying to reverse some merged works, an error is thrown. 
```
/openlibrary/openlibrary/templates/books/RelatedWorksCarousel.html: error in processing template: TypeError: Object of type Nothing is not JSON serializable (falling back to default template)
Hmm...
Sorry. There seems to be a problem with what you were just looking at.

We've noted the error 2021-10-12/170342688830 and will look into it as soon as possible. Head for home?
```
### Evidence / Screenshot (if possible)

### Relevant url?
https://openlibrary.org/works/OL14918267W?v=2&m=revert
https://openlibrary.org/works/OL23224294W?v=2

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Go to ...a deleted work
2. Do ...roll back to an earlier version

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual: see error above
* Expected:  previous version should be restored

### Details

- **Logged in (Y/N)?** 
- **Browser type/version?** 
- **Operating system?** 
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->
@jimchamp 


Discussion:
Hey @jimchamp , I would like to work on this issue. Can you assign it to me?

Resolving patch:
diff --git a/openlibrary/core/cache.py b/openlibrary/core/cache.py
--- a/openlibrary/core/cache.py
+++ b/openlibrary/core/cache.py
@@ -12,9 +12,11 @@
 
 from infogami import config
 from infogami.utils import stats
+from infogami.infobase.client import Nothing
 
 from openlibrary.utils import olmemcache
 from openlibrary.utils.dateutil import MINUTE_SECS
+from openlibrary.core.helpers import NothingEncoder
 
 import six
 
@@ -191,7 +193,7 @@ def json_encode(self, value):
 
         memcache doesn't like spaces in the key.
         """
-        return json.dumps(value, separators=(",", ":"))
+        return json.dumps([] if isinstance(value, Nothing) else value, separators=(",", ":"), cls=NothingEncoder)
 
     def memcache_set(self, args, kw, value, time):
         """Adds value and time to memcache. Key is computed from the arguments."""
@@ -556,7 +558,6 @@ def json_encode(self, value):
         """
         return json.dumps(value, separators=(",", ":"), sort_keys=True)
 
-
 def method_memoize(f):
     """
     object-local memoize.


Test patch: