We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
smartplaylist: Respect sort terms in queries
It would be nice to be able sort items in smart playlists, like so:

```
smartplaylist:
  relative_to: ~/music
  playlist_dir: ~/.mpd/playlists
  playlists:
    - name: '2014.m3u'
      query: 'year:2014 added+'
    - name: 'imported-%time{$added,%Y-%m}.m3u'
      query: "added:: path+"
```

I'm unfamiliar with the code but it looks like the smartplaylist plugin [discards the query `sort` field](https://github.com/sampsyo/beets/blob/master/beetsplug/smartplaylist.py#L45) when building playlists. Would it be possible to keep the custom sort?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `beetsplug/smartplaylist.py`
Content:
```
1 # This file is part of beets.
2 # Copyright 2013, Dang Mai <contact@dangmai.net>.
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
11 #
12 # The above copyright notice and this permission notice shall be
13 # included in all copies or substantial portions of the Software.
14 
15 """Generates smart playlists based on beets queries.
16 """
17 from __future__ import print_function
18 
19 from beets.plugins import BeetsPlugin
20 from beets import config, ui, library
21 from beets import dbcore
22 from beets.util import normpath, syspath
23 import os
24 
25 # Global variable so that smartplaylist can detect database changes and run
26 # only once before beets exits.
27 database_changed = False
28 
29 
30 def _items_for_query(lib, playlist, album=False):
31     """Get the matching items for a playlist's configured queries.
32     `album` indicates whether to process the item-level query or the
33     album-level query (if any).
34     """
35     key = 'album_query' if album else 'query'
36     if key not in playlist:
37         return []
38 
39     # Parse quer(ies). If it's a list, join the queries with OR.
40     query_strings = playlist[key]
41     if not isinstance(query_strings, (list, tuple)):
42         query_strings = [query_strings]
43     model = library.Album if album else library.Item
44     query = dbcore.OrQuery(
45         [library.parse_query_string(q, model)[0] for q in query_strings]
46     )
47 
48     # Execute query, depending on type.
49     if album:
50         result = []
51         for album in lib.albums(query):
52             result.extend(album.items())
53         return result
54     else:
55         return lib.items(query)
56 
57 
58 def update_playlists(lib):
59     ui.print_("Updating smart playlists...")
60     playlists = config['smartplaylist']['playlists'].get(list)
61     playlist_dir = config['smartplaylist']['playlist_dir'].as_filename()
62     relative_to = config['smartplaylist']['relative_to'].get()
63     if relative_to:
64         relative_to = normpath(relative_to)
65 
66     for playlist in playlists:
67         items = []
68         items.extend(_items_for_query(lib, playlist, True))
69         items.extend(_items_for_query(lib, playlist, False))
70 
71         m3us = {}
72         basename = playlist['name'].encode('utf8')
73         # As we allow tags in the m3u names, we'll need to iterate through
74         # the items and generate the correct m3u file names.
75         for item in items:
76             m3u_name = item.evaluate_template(basename, True)
77             if not (m3u_name in m3us):
78                 m3us[m3u_name] = []
79             item_path = item.path
80             if relative_to:
81                 item_path = os.path.relpath(item.path, relative_to)
82             if item_path not in m3us[m3u_name]:
83                 m3us[m3u_name].append(item_path)
84         # Now iterate through the m3us that we need to generate
85         for m3u in m3us:
86             m3u_path = normpath(os.path.join(playlist_dir, m3u))
87             with open(syspath(m3u_path), 'w') as f:
88                 for path in m3us[m3u]:
89                     f.write(path + '\n')
90     ui.print_("... Done")
91 
92 
93 class SmartPlaylistPlugin(BeetsPlugin):
94     def __init__(self):
95         super(SmartPlaylistPlugin, self).__init__()
96         self.config.add({
97             'relative_to': None,
98             'playlist_dir': u'.',
99             'auto': True,
100             'playlists': []
101         })
102 
103     def commands(self):
104         def update(lib, opts, args):
105             update_playlists(lib)
106         spl_update = ui.Subcommand('splupdate',
107                                    help='update the smart playlists')
108         spl_update.func = update
109         return [spl_update]
110 
111 
112 @SmartPlaylistPlugin.listen('database_change')
113 def handle_change(lib):
114     global database_changed
115     database_changed = True
116 
117 
118 @SmartPlaylistPlugin.listen('cli_exit')
119 def update(lib):
120     auto = config['smartplaylist']['auto']
121     if database_changed and auto:
122         update_playlists(lib)
123
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py
--- a/beetsplug/smartplaylist.py
+++ b/beetsplug/smartplaylist.py
@@ -18,7 +18,6 @@
 
 from beets.plugins import BeetsPlugin
 from beets import config, ui, library
-from beets import dbcore
 from beets.util import normpath, syspath
 import os
 
@@ -36,23 +35,21 @@
     if key not in playlist:
         return []
 
-    # Parse quer(ies). If it's a list, join the queries with OR.
+    # Parse quer(ies). If it's a list, perform the queries and manually
+    # concatenate the results
     query_strings = playlist[key]
     if not isinstance(query_strings, (list, tuple)):
         query_strings = [query_strings]
     model = library.Album if album else library.Item
-    query = dbcore.OrQuery(
-        [library.parse_query_string(q, model)[0] for q in query_strings]
-    )
-
-    # Execute query, depending on type.
-    if album:
-        result = []
-        for album in lib.albums(query):
-            result.extend(album.items())
-        return result
-    else:
-        return lib.items(query)
+    results = []
+    for q in query_strings:
+        querystr, sort = library.parse_query_string(q, model)
+        if album:
+            new = lib.albums(querystr, sort)
+        else:
+            new = lib.items(querystr, sort)
+        results.extend(new)
+    return results
 
 
 def update_playlists(lib):

{"golden_diff": "diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py\n--- a/beetsplug/smartplaylist.py\n+++ b/beetsplug/smartplaylist.py\n@@ -18,7 +18,6 @@\n \n from beets.plugins import BeetsPlugin\n from beets import config, ui, library\n-from beets import dbcore\n from beets.util import normpath, syspath\n import os\n \n@@ -36,23 +35,21 @@\n     if key not in playlist:\n         return []\n \n-    # Parse quer(ies). If it's a list, join the queries with OR.\n+    # Parse quer(ies). If it's a list, perform the queries and manually\n+    # concatenate the results\n     query_strings = playlist[key]\n     if not isinstance(query_strings, (list, tuple)):\n         query_strings = [query_strings]\n     model = library.Album if album else library.Item\n-    query = dbcore.OrQuery(\n-        [library.parse_query_string(q, model)[0] for q in query_strings]\n-    )\n-\n-    # Execute query, depending on type.\n-    if album:\n-        result = []\n-        for album in lib.albums(query):\n-            result.extend(album.items())\n-        return result\n-    else:\n-        return lib.items(query)\n+    results = []\n+    for q in query_strings:\n+        querystr, sort = library.parse_query_string(q, model)\n+        if album:\n+            new = lib.albums(querystr, sort)\n+        else:\n+            new = lib.items(querystr, sort)\n+        results.extend(new)\n+    return results\n \n \n def update_playlists(lib):\n", "issue": "smartplaylist: Respect sort terms in queries\nIt would be nice to be able sort items in smart playlists, like so:\n\n```\nsmartplaylist:\n  relative_to: ~/music\n  playlist_dir: ~/.mpd/playlists\n  playlists:\n    - name: '2014.m3u'\n      query: 'year:2014 added+'\n    - name: 'imported-%time{$added,%Y-%m}.m3u'\n      query: \"added:: path+\"\n```\n\nI'm unfamiliar with the code but it looks like the smartplaylist plugin [discards the query `sort` field](https://github.com/sampsyo/beets/blob/master/beetsplug/smartplaylist.py#L45) when building playlists. Would it be possible to keep the custom sort?\n\n", "before_files": [{"content": "# This file is part of beets.\n# Copyright 2013, Dang Mai <contact@dangmai.net>.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Generates smart playlists based on beets queries.\n\"\"\"\nfrom __future__ import print_function\n\nfrom beets.plugins import BeetsPlugin\nfrom beets import config, ui, library\nfrom beets import dbcore\nfrom beets.util import normpath, syspath\nimport os\n\n# Global variable so that smartplaylist can detect database changes and run\n# only once before beets exits.\ndatabase_changed = False\n\n\ndef _items_for_query(lib, playlist, album=False):\n    \"\"\"Get the matching items for a playlist's configured queries.\n    `album` indicates whether to process the item-level query or the\n    album-level query (if any).\n    \"\"\"\n    key = 'album_query' if album else 'query'\n    if key not in playlist:\n        return []\n\n    # Parse quer(ies). If it's a list, join the queries with OR.\n    query_strings = playlist[key]\n    if not isinstance(query_strings, (list, tuple)):\n        query_strings = [query_strings]\n    model = library.Album if album else library.Item\n    query = dbcore.OrQuery(\n        [library.parse_query_string(q, model)[0] for q in query_strings]\n    )\n\n    # Execute query, depending on type.\n    if album:\n        result = []\n        for album in lib.albums(query):\n            result.extend(album.items())\n        return result\n    else:\n        return lib.items(query)\n\n\ndef update_playlists(lib):\n    ui.print_(\"Updating smart playlists...\")\n    playlists = config['smartplaylist']['playlists'].get(list)\n    playlist_dir = config['smartplaylist']['playlist_dir'].as_filename()\n    relative_to = config['smartplaylist']['relative_to'].get()\n    if relative_to:\n        relative_to = normpath(relative_to)\n\n    for playlist in playlists:\n        items = []\n        items.extend(_items_for_query(lib, playlist, True))\n        items.extend(_items_for_query(lib, playlist, False))\n\n        m3us = {}\n        basename = playlist['name'].encode('utf8')\n        # As we allow tags in the m3u names, we'll need to iterate through\n        # the items and generate the correct m3u file names.\n        for item in items:\n            m3u_name = item.evaluate_template(basename, True)\n            if not (m3u_name in m3us):\n                m3us[m3u_name] = []\n            item_path = item.path\n            if relative_to:\n                item_path = os.path.relpath(item.path, relative_to)\n            if item_path not in m3us[m3u_name]:\n                m3us[m3u_name].append(item_path)\n        # Now iterate through the m3us that we need to generate\n        for m3u in m3us:\n            m3u_path = normpath(os.path.join(playlist_dir, m3u))\n            with open(syspath(m3u_path), 'w') as f:\n                for path in m3us[m3u]:\n                    f.write(path + '\\n')\n    ui.print_(\"... Done\")\n\n\nclass SmartPlaylistPlugin(BeetsPlugin):\n    def __init__(self):\n        super(SmartPlaylistPlugin, self).__init__()\n        self.config.add({\n            'relative_to': None,\n            'playlist_dir': u'.',\n            'auto': True,\n            'playlists': []\n        })\n\n    def commands(self):\n        def update(lib, opts, args):\n            update_playlists(lib)\n        spl_update = ui.Subcommand('splupdate',\n                                   help='update the smart playlists')\n        spl_update.func = update\n        return [spl_update]\n\n\n@SmartPlaylistPlugin.listen('database_change')\ndef handle_change(lib):\n    global database_changed\n    database_changed = True\n\n\n@SmartPlaylistPlugin.listen('cli_exit')\ndef update(lib):\n    auto = config['smartplaylist']['auto']\n    if database_changed and auto:\n        update_playlists(lib)\n", "path": "beetsplug/smartplaylist.py"}], "after_files": [{"content": "# This file is part of beets.\n# Copyright 2013, Dang Mai <contact@dangmai.net>.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Generates smart playlists based on beets queries.\n\"\"\"\nfrom __future__ import print_function\n\nfrom beets.plugins import BeetsPlugin\nfrom beets import config, ui, library\nfrom beets.util import normpath, syspath\nimport os\n\n# Global variable so that smartplaylist can detect database changes and run\n# only once before beets exits.\ndatabase_changed = False\n\n\ndef _items_for_query(lib, playlist, album=False):\n    \"\"\"Get the matching items for a playlist's configured queries.\n    `album` indicates whether to process the item-level query or the\n    album-level query (if any).\n    \"\"\"\n    key = 'album_query' if album else 'query'\n    if key not in playlist:\n        return []\n\n    # Parse quer(ies). If it's a list, perform the queries and manually\n    # concatenate the results\n    query_strings = playlist[key]\n    if not isinstance(query_strings, (list, tuple)):\n        query_strings = [query_strings]\n    model = library.Album if album else library.Item\n    results = []\n    for q in query_strings:\n        querystr, sort = library.parse_query_string(q, model)\n        if album:\n            new = lib.albums(querystr, sort)\n        else:\n            new = lib.items(querystr, sort)\n        results.extend(new)\n    return results\n\n\ndef update_playlists(lib):\n    ui.print_(\"Updating smart playlists...\")\n    playlists = config['smartplaylist']['playlists'].get(list)\n    playlist_dir = config['smartplaylist']['playlist_dir'].as_filename()\n    relative_to = config['smartplaylist']['relative_to'].get()\n    if relative_to:\n        relative_to = normpath(relative_to)\n\n    for playlist in playlists:\n        items = []\n        items.extend(_items_for_query(lib, playlist, True))\n        items.extend(_items_for_query(lib, playlist, False))\n\n        m3us = {}\n        basename = playlist['name'].encode('utf8')\n        # As we allow tags in the m3u names, we'll need to iterate through\n        # the items and generate the correct m3u file names.\n        for item in items:\n            m3u_name = item.evaluate_template(basename, True)\n            if not (m3u_name in m3us):\n                m3us[m3u_name] = []\n            item_path = item.path\n            if relative_to:\n                item_path = os.path.relpath(item.path, relative_to)\n            if item_path not in m3us[m3u_name]:\n                m3us[m3u_name].append(item_path)\n        # Now iterate through the m3us that we need to generate\n        for m3u in m3us:\n            m3u_path = normpath(os.path.join(playlist_dir, m3u))\n            with open(syspath(m3u_path), 'w') as f:\n                for path in m3us[m3u]:\n                    f.write(path + '\\n')\n    ui.print_(\"... Done\")\n\n\nclass SmartPlaylistPlugin(BeetsPlugin):\n    def __init__(self):\n        super(SmartPlaylistPlugin, self).__init__()\n        self.config.add({\n            'relative_to': None,\n            'playlist_dir': u'.',\n            'auto': True,\n            'playlists': []\n        })\n\n    def commands(self):\n        def update(lib, opts, args):\n            update_playlists(lib)\n        spl_update = ui.Subcommand('splupdate',\n                                   help='update the smart playlists')\n        spl_update.func = update\n        return [spl_update]\n\n\n@SmartPlaylistPlugin.listen('database_change')\ndef handle_change(lib):\n    global database_changed\n    database_changed = True\n\n\n@SmartPlaylistPlugin.listen('cli_exit')\ndef update(lib):\n    auto = config['smartplaylist']['auto']\n    if database_changed and auto:\n        update_playlists(lib)\n", "path": "beetsplug/smartplaylist.py"}]}