Beispiel #1
0
    def get_text_matches(self, text, channel=None):
        """Do text search lookup

        Args:
            text (str): text to search for.
            channel (str): URL of the channel.
        """
        query = """
        SELECT
          nie:url(?msg) AS ?url
          nie:title(?msg) AS ?title
          nco:fullname(?creator) AS ?fullname
          nie:url(?website) AS ?author_homepage
          nco:emailAddress(?email) AS ?author_email
          nie:contentCreated(?msg) AS ?date_created
          nmo:htmlMessageContent(?msg) AS ?content
          nmo:isRead(?msg) AS ?is_read
          ?msg BOUND(?tag) AS ?is_starred
          { ?msg a mfo:FeedMessage; """

        if channel:
            query += """
                nmo:communicationChannel ?chan;
                ?chan nie:url "%s" . """

        query += """
                 fts:match "%s" .
            OPTIONAL { ?msg nco:creator ?creator .
                       ?msg nao:hasTag ?tag .
                       FILTER(?tag = nao:predefined-tag-favorite) .
                       OPTIONAL { ?creator nco:hasEmailAddress ?email } .
                       OPTIONAL { ?creator nco:websiteUrl ?website }}
          }
        ORDER BY fts:rank(?msg)
        """

        if channel:
            query = query % Trackr.sparql_escape_string(text), channel
        else:
            query = query % Trackr.sparql_escape_string(text)

        try:
            results = self.sparql.query(query)
            ret = []
            while (results.next(None)):
                ret.append(self.parse_sparql(results))
            return ret
        except Exception:
            return []
Beispiel #2
0
    def get_text_matches(self, text, channel=None):
        """Do text search lookup

        Args:
            text (str): text to search for.
            channel (str): URL of the channel.
        """
        query = """
        SELECT
          nie:url(?msg) AS ?url
          nie:title(?msg) AS ?title
          nco:fullname(?creator) AS ?fullname
          nie:url(?website) AS ?author_homepage
          nco:emailAddress(?email) AS ?author_email
          nie:contentCreated(?msg) AS ?date_created
          nmo:htmlMessageContent(?msg) AS ?content
          nmo:isRead(?msg) AS ?is_read
          ?msg BOUND(?tag) as ?is_starred
          { ?msg a mfo:FeedMessage; """

        if channel:
            query += """
                nmo:communicationChannel ?chan;
                ?chan nie:url "%s" . """

        query += """
                 fts:match "%s" .
            OPTIONAL { ?msg nco:creator ?creator .
                       ?msg nao:hasTag ?tag .
                       FILTER(?tag = nao:predefined-tag-favorite) .
                       OPTIONAL { ?creator nco:hasEmailAddress ?email } .
                       OPTIONAL { ?creator nco:websiteUrl ?website }}
          }
        ORDER BY fts:rank(?msg)
        """

        if channel:
            query = query % Trackr.sparql_escape_string(text), channel
        else:
            query = query % Trackr.sparql_escape_string(text)

        try:
            results = self.sparql.query(query)
            ret = []
            while (results.next(None)):
                ret.append(self.parse_sparql(results))
            return ret
        except Exception:
            return []
Beispiel #3
0
    def tracks(self,
               filter_artist_name=None,
               filter_album_name=None,
               track_search_text=None):
        '''Return a list of tracks.'''

        if track_search_text:
            track_pattern = """
                FILTER (fn:contains(LCASE(?track_title), "%s"))
            """ % Tracker.sparql_escape_string(track_search_text.lower())
        else:
            track_pattern = " "

        if filter_artist_name:
            artist_pattern = 'FILTER (LCASE(?artist_name) = "%s")' % \
                Tracker.sparql_escape_string(filter_artist_name.lower())
        else:
            artist_pattern = " "

        if filter_album_name:
            album_pattern = """
                ?track nmm:musicAlbum [ nie:title ?albumTitle ] .
                FILTER (LCASE(?albumTitle) = "%s")
            """ % Tracker.sparql_escape_string(filter_album_name.lower())
        else:
            album_pattern = ""

        query_tracks = """
        SELECT
            ?track_title ?track_url ?artist_name
        WHERE {
            ?track a nmm:MusicPiece ;
              dc:title ?track_title ;
              nie:url ?track_url ;
              nmm:performer ?artist .
            %s %s %s
            ?artist nmm:artistName ?artist_name .
        }
        ORDER BY ?track_title ?artist_name
        """ % (track_pattern, artist_pattern, album_pattern)

        tracks = self.query(query_tracks)
        while tracks.next():
            yield {
                'track': tracks.get_string(0)[0],
                'artist': tracks.get_string(2)[0],
                'tracker.url': tracks.get_string(1)[0],
            }
Beispiel #4
0
    def get_songs_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_normalize(GLib.utf8_casefold(name, -1), -1, GLib.NormalizeMode.NFKD))
        query = """
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    BIND(tracker:normalize(nie:title(nmm:musicAlbum(?song)), 'nfkd') AS ?match1) .
                    BIND(tracker:normalize(nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
                    BIND(tracker:normalize(nie:title(?song), 'nfkd') AS ?match3) .
                    BIND(tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
                    FILTER (
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match1)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match1), "%(name)s") ||
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match2)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match2), "%(name)s") ||
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match3)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match3), "%(name)s") ||
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match4)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match4), "%(name)s")
                    )
                }
            }
            """.replace('\n', ' ').strip() % {'name': name}

        return Query.songs(query)
Beispiel #5
0
    def get_songs_with_any_match(name):
        name = Tracker.sparql_escape_string(
            GLib.utf8_normalize(GLib.utf8_casefold(name, -1), -1,
                                GLib.NormalizeMode.NFKD))
        query = """
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    BIND(tracker:normalize(nie:title(nmm:musicAlbum(?song)), 'nfkd') AS ?match1) .
                    BIND(tracker:normalize(nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
                    BIND(tracker:normalize(nie:title(?song), 'nfkd') AS ?match3) .
                    FILTER (
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match1)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match1), "%(name)s") ||
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match2)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match2), "%(name)s") ||
                        CONTAINS(tracker:case-fold(tracker:unaccent(?match3)), "%(name)s") ||
                        CONTAINS(tracker:case-fold(?match3), "%(name)s")
                    )
                }
            }
            """.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)
Beispiel #6
0
    def get_songs_with_artist_match(name):
        name = Tracker.sparql_escape_string(name)
        query = '?performer fts:match "nmm:artistName: %(name)s*" . '.replace(
            '\n', ' ').strip() % {
                'name': name
            }

        return Query.songs(query)
Beispiel #7
0
    def get_songs_with_album_match(name):
        name = Tracker.sparql_escape_string(name)
        query = '?album fts:match "nie:title: %(name)s*" . '.replace(
            '\n', ' ').strip() % {
                'name': name
            }

        return Query.songs(query)
Beispiel #8
0
    def get_songs_with_composer_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?song nmm:composer [ fts:match '%(name)s*' ] . """.replace(
            '\n', ' ').strip() % {
                'name': name
            }

        return Query.songs(query)
Beispiel #9
0
    def get_albums_with_album_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?album fts:match '"nie:title" : %(name)s*' . """.replace(
            '\n', ' ').strip() % {
                'name': name
            }

        return Query.albums(query)
Beispiel #10
0
    def get_artists_with_artist_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?performer fts:match '"nmm:artistName" : %(name)s*' . """.replace(
            '\n', ' ').strip() % {
                'name': name
            }

        return Query.artists(query)
Beispiel #11
0
    def get_artists_with_track_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?song fts:match '"nie:title" : %(name)s*' . """.replace(
            '\n', ' ').strip() % {
                'name': name
            }

        return Query.artists(query)
Beispiel #12
0
    def tracks(self, filter_artist_name=None, filter_album_name=None, track_search_text=None):
        '''Return a list of tracks.'''

        if track_search_text:
            track_pattern = """
                FILTER (fn:contains(LCASE(?track_title), "%s"))
            """  % Tracker.sparql_escape_string(track_search_text.lower())
        else:
            track_pattern = " "

        if filter_artist_name:
            artist_pattern = 'FILTER (LCASE(?artist_name) = "%s")' % \
                Tracker.sparql_escape_string(filter_artist_name.lower())
        else:
            artist_pattern =" "

        if filter_album_name:
            album_pattern = """
                ?track nmm:musicAlbum [ nie:title ?albumTitle ] .
                FILTER (LCASE(?albumTitle) = "%s")
            """  % Tracker.sparql_escape_string(filter_album_name.lower())
        else:
            album_pattern = ""

        query_tracks = """
        SELECT
            ?track_title ?track_url ?artist_name
        WHERE {
            ?track a nmm:MusicPiece ;
              dc:title ?track_title ;
              nie:url ?track_url ;
              nmm:performer ?artist .
            %s %s %s
            ?artist nmm:artistName ?artist_name .
        }
        ORDER BY ?track_title ?artist_name
        """ % (track_pattern, artist_pattern, album_pattern)

        tracks = self.query(query_tracks)
        while tracks.next():
            yield {
                'track': tracks.get_string(0)[0],
                'artist': tracks.get_string(2)[0],
                'tracker.url': tracks.get_string(1)[0],
            }
Beispiel #13
0
    def set_text(self, text):
        text_escaped = Tracker.sparql_escape_string(text)
        path = pathlib.Path(self.path(self.testfile))

        if path.exists():
            old_text_escaped = Tracker.sparql_escape_string(path.read_text())
            resource_id = self.tracker.get_content_resource_id(self.uri(self.testfile))
            with self.tracker.await_content_update(DOCUMENTS_GRAPH,
                                                   resource_id,
                                                   f'nie:plainTextContent "{old_text_escaped}"',
                                                   f'nie:plainTextContent "{text_escaped}"',
                                                   timeout=cfg.AWAIT_TIMEOUT):
                path.write_text(text)
        else:
            url = self.uri(self.testfile)
            expected = f'a nfo:Document; nie:isStoredAs <{url}>; nie:plainTextContent "{text_escaped}"'
            with self.tracker.await_insert(DOCUMENTS_GRAPH, expected, timeout=cfg.AWAIT_TIMEOUT):
                path.write_text(text)
Beispiel #14
0
    def get_songs_with_composer_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """
            ?song nmm:composer ?composer .
            ?composer fts:match '"nmm:artistName" : %(name)s*' .
        """.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)
Beispiel #15
0
    def get_albums_with_composer_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """
            ?song nmm:composer ?composer .
            ?composer fts:match '"nmm:artistName" : %(name)s*' .
        """.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)
Beispiel #16
0
    def create_playlist(self, playlist_title, callback):
        """Creates a new user playlist.

        :param str playlist_title: playlist title
        :param callback: function to perform once, the playlist is created
        """
        def _create_cb(conn, res, data):
            try:
                result = conn.update_blank_finish(res)
            except GLib.Error as error:
                self._log.warning(
                    "Unable to create playlist {}: {}".format(
                        playlist_title, error.message))
                self._notificationmanager.pop_loading()
                if callback is not None:
                    callback(None)

                return

            playlist_urn = result[0][0]['playlist']
            query = """
            SELECT
                %(media_type)s AS ?type
                ?playlist AS ?id
                nie:title(?playlist) AS ?title
                nrl:added(?playlist) AS ?creationDate
                nfo:entryCounter(?playlist) AS ?childCount
                WHERE
                {
                    BIND ( <%(playlist_urn)s> AS ?playlist )
                }
            """.replace("\n", " ").strip() % {
                "media_type": int(Grl.MediaType.CONTAINER),
                "playlist_urn": playlist_urn
            }

            self._source.query(
                query, self._METADATA_PLAYLIST_KEYS, self._fast_options,
                self._add_user_playlist, callback)

        self._notificationmanager.push_loading()
        query = """
            INSERT {
                _:playlist a nmm:Playlist ;
                           a nfo:MediaList ;
                             nie:title "%(title)s" ;
                             nfo:entryCounter 0 .
            }
            """.replace("\n", " ").strip() % {
                "title": Tracker.sparql_escape_string(playlist_title)
        }
        self._tracker.update_blank_async(query, None, _create_cb, None)
Beispiel #17
0
    def __init__(self):
        try:
            Query.music_folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
            assert Query.music_folder is not None
        except (TypeError, AssertionError):
            logger.warn("XDG Music dir is not set")
            return

        Query.MUSIC_URI = Tracker.sparql_escape_string(GLib.filename_to_uri(Query.music_folder))

        for folder in [Query.music_folder]:
            if os.path.islink(folder):
                logger.warn("%s is a symlink, this folder will be omitted", folder)
Beispiel #18
0
    def __init__(self):
        try:
            Query.music_folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
            assert Query.music_folder is not None
        except (TypeError, AssertionError):
            logger.warning("XDG Music dir is not set")
            return

        Query.MUSIC_URI = Tracker.sparql_escape_string(GLib.filename_to_uri(Query.music_folder))

        for folder in [Query.music_folder]:
            if os.path.islink(folder):
                logger.warning("{} is a symlink, this folder will be omitted".format(folder))
def albums_query (artist):
    artist = Tracker.sparql_escape_string(artist)
    return """
    SELECT ?album_name ?album
    WHERE {
        ?album a nmm:MusicAlbum;
            nmm:albumArtist "%s";
            nmm:albumTitle ?album_name.
        # make sure the album isn't empty
        ?song nmm:musicAlbum ?album .
    }
    GROUP BY ?album
    ORDER BY ?album_name
    """ % (artist, )
Beispiel #20
0
    def __init__(self):
        try:
            Query.music_folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
            assert Query.music_folder is not None
        except (TypeError, AssertionError):
            logger.warn("XDG Music dir is not set")
            return

        try:
            Query.download_folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            assert Query.download_folder is not None
        except (TypeError, AssertionError):
            logger.warn("XDG Download dir is not set")
            return

        Query.MUSIC_URI = Tracker.sparql_escape_string(GLib.filename_to_uri(Query.music_folder))
        Query.DOWNLOAD_URI = Tracker.sparql_escape_string(GLib.filename_to_uri(Query.download_folder))

        for folder in [Query.music_folder, Query.download_folder]:
            if os.path.islink(folder):
                logger.warn("%s is a symlink, this folder will be omitted", folder)
            else:
                i = len(next(os.walk(folder))[2])
                logger.debug("Found %d files in %s", i, folder)
def songs_query (album):
    album = Tracker.sparql_escape_string(album)
    return """
    SELECT ?song_name ?song ?filename
    WHERE {
        ?song a nmm:MusicPiece;
            nmm:musicAlbum "%s";
            nmm:trackNumber ?trackNumber;
            nie:title ?song_name ;
            nie:url ?filename ;
            nmm:musicAlbumDisc [nmm:setNumber ?disc_number].
    }
    # need to also sort by disk number
    ORDER BY ?disc_number ?trackNumber
    """ % (album, )
    def location_filter(self):
        try:
            music_dir = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
            assert music_dir is not None
        except (TypeError, AssertionError):
            self._log.message("XDG Music dir is not set")
            return None

        music_dir = Tracker.sparql_escape_string(
            GLib.filename_to_uri(music_dir))

        query = "FILTER (STRSTARTS(nie:isStoredAs(?song), '{}/'))".format(
            music_dir)

        return query
Beispiel #23
0
    def get_artists_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?album)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {'name': name}

        return Query.artists(query)
Beispiel #24
0
    def get_songs_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {'name': name}

        return Query.songs(query)
Beispiel #25
0
    def __init__(self):
        try:
            Query.music_folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
            assert Query.music_folder is not None
        except (TypeError, AssertionError):
            logger.warn("XDG Music dir is not set")
            return

        Query.MUSIC_URI = Tracker.sparql_escape_string(GLib.filename_to_uri(Query.music_folder))

        for folder in [Query.music_folder]:
            if os.path.islink(folder):
                logger.warn("%s is a symlink, this folder will be omitted", folder)
            else:
                i = len(next(os.walk(folder)))
                logger.debug("Found %d files in %s", i, folder)
Beispiel #26
0
    def await_document_inserted(self, path, content=None):
        """Wraps await_insert() context manager."""
        if isinstance(path, pathlib.Path):
            url = path.as_uri()
        else:
            url = self.uri(path)

        expected = [
            'a nfo:Document',
            f'nie:isStoredAs <{url}>',
        ]

        if content:
            content_escaped = Tracker.sparql_escape_string(content)
            expected += [f'nie:plainTextContent "{content_escaped}"']

        return self.tracker.await_insert(DOCUMENTS_GRAPH, '; '.join(expected), timeout=cfg.AWAIT_TIMEOUT)
    def _setup_local_db(self):
        # Open a local Tracker database.
        try:
            self._local_db = Tracker.SparqlConnection.new(
                Tracker.SparqlConnectionFlags.NONE,
                Gio.File.new_for_path(self.cache_directory()),
                Tracker.sparql_get_ontology_nepomuk(), None)
        except GLib.Error as error:
            self._log.warning("Error: {}, {}".format(error.domain,
                                                     error.message))
            self.notify("tracker-available")
            return

        # Version checks against the local version of Tracker can be done
        # here, set `self._tracker_available = TrackerState.OUTDATED` if the
        # checks fail.
        self._local_db_available = TrackerState.AVAILABLE
        self.notify("tracker-available")
Beispiel #28
0
    def get_artists_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {'name': name}

        return Query.artists(query)
Beispiel #29
0
    def get_songs_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)
Beispiel #30
0
    def get_artists_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?album)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)
Beispiel #31
0
    def _location_filter():
        try:
            music_dir = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
            assert music_dir is not None
        except (TypeError, AssertionError):
            print("XDG Music dir is not set")
            return

        music_dir = Tracker.sparql_escape_string(
            GLib.filename_to_uri(music_dir))

        query = """
        FILTER (STRSTARTS(nie:url(?song), '%(music_dir)s/'))
        """.replace('\n', ' ').strip() % {
            'music_dir': music_dir
        }

        return query
Beispiel #32
0
    def new_feed_item_signal(self, fetcher, feed, item):
        try:
            uri = item.get_source()
            # if self.get_info_for_entry(uri) is not None:
            #     logger.info("Item %s is already added" % uri)
            #     return

            source_uri = feed.get_source()
            timestamp = item.get_publish_time()
            author = item.get_author()
            date = datetime.fromtimestamp(timestamp).isoformat()
            title = item.get_title()
            text = item.get_description()
            escaped_text = Tracker.sparql_escape_string(text)

            query = INSERT_QUERY % (uri, date, source_uri, author, escaped_text, title)
            logger.info("New feed: \n%s" % query)
            self.iface.SparqlUpdate(query)
        except Exception as e:
            logger.warn(str(e))
Beispiel #33
0
    def get_artists_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)
Beispiel #34
0
    def get_songs_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = """
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s")
                    )
                }
            }
            """.replace(
            "\n", " "
        ).strip() % {
            "name": name
        }

        return Query.songs(query)
    def title(self, new_name):
        """Rename a playlist

        :param str new_name: new playlist name
        """
        self._notificationmanager.push_loading()

        def update_cb(conn, res, data):
            try:
                conn.update_finish(res)
            except GLib.Error as e:
                self._log.warning(
                    "Unable to rename playlist from {} to {}: {}".format(
                        self._title, new_name, e.message))
            else:
                self._title = new_name
            finally:
                self._notificationmanager.pop_loading()
                self.thaw_notify()

        query = """
        INSERT OR REPLACE {
            ?playlist nie:title "%(title)s"
        }
        WHERE {
            ?playlist a nmm:Playlist ;
                      a nfo:MediaList .
            OPTIONAL {
                ?playlist nfo:hasMediaFileListEntry ?entry .
            }
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
        """.replace("\n", " ").strip() % {
            'title': Tracker.sparql_escape_string(new_name),
            'playlist_id': self.props.pl_id
        }

        self.freeze_notify()
        self._tracker.update_async(query, None, update_cb, None)
Beispiel #36
0
def main():
    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    tmpdir = tempfile.mkdtemp(prefix='tracker-test-')

    # Where the database is stored.
    store_path = Gio.File.new_for_path(tmpdir)

    # The database schemas.
    ontology_path = Tracker.sparql_get_ontology_nepomuk()
    if 'TEST_ONTOLOGIES_DIR' in os.environ:
        ontology_path = Gio.File.new_for_path(
            os.environ['TEST_ONTOLOGIES_DIR'])

    cancellable = None

    # Create a new, empty database.
    conn = Tracker.SparqlConnection.new(Tracker.SparqlConnectionFlags.NONE,
                                        store_path, ontology_path, cancellable)

    bus = Gio.bus_get_sync(Gio.BusType.SESSION, cancellable)
    unique_name = bus.get_unique_name()

    # Publish our endpoint on DBus.
    endpoint = Tracker.EndpointDBus.new(conn, bus, None, cancellable)

    print(f"Exposing a Tracker endpoint on bus name {unique_name}")
    print()
    print(f"Try connecting over D-Bus using `tracker3 sparql`:")
    print()
    print(f"   tracker3 sparql --dbus-service={unique_name} -q ...")

    loop = GLib.MainLoop.new(None, False)

    if os.environ.get('TRACKER_EXAMPLES_AUTOMATED_TEST'):
        GLib.timeout_add(10, lambda *args: loop.quit(), None)
    else:
        print()
        print(f"Press CTRL+C to quit.")

    loop.run()
Beispiel #37
0
    def get_artists_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = """
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum ;
                        nmm:albumArtist ?artist .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(?artist)), "%(name)s")
                    )
                }
            }
            """.replace(
            "\n", " "
        ).strip() % {
            "name": name
        }

        return Query.artists(query)
Beispiel #38
0
    def ensure_document_inserted(self, path, content=None):
        """Block until document is inserted.

        Use this if insertion may already have happened."""

        if isinstance(path, pathlib.Path):
            url = path.as_uri()
        else:
            url = self.uri(path)

        expected = [
            'a nfo:Document',
            f'nie:isStoredAs <{url}>',
        ]

        if content:
            content_escaped = Tracker.sparql_escape_string(content)
            expected += [f'nie:plainTextContent "{content_escaped}"']

        return self.tracker.ensure_resource(DOCUMENTS_GRAPH,
                                            ';'.join(expected),
                                            timeout=cfg.AWAIT_TIMEOUT)
Beispiel #39
0
    def __init__(self):
        super().__init__()

        # FIXME: This is now duplicated here and in GrlTrackerWrapper.
        try:
            music_folder = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
            assert music_folder is not None
        except (TypeError, AssertionError):
            print("XDG Music dir is not set")
            return

        music_folder = Tracker.sparql_escape_string(
            GLib.filename_to_uri(music_folder))

        href_text = "<a href='{}'>{}</a>".format(music_folder,
                                                 _("Music folder"))

        # TRANSLATORS: This is a label to display a link to open user's music
        # folder. {} will be replaced with the translated text 'Music folder'
        folder_text = _("The contents of your {} will appear here.")
        self._content_text = folder_text.format(href_text)

        self._state = EmptyView.State.INITIAL
Beispiel #40
0
    def get_songs_with_artist_match(name):
        name = Tracker.sparql_escape_string(name)
        query = '?performer fts:match "nmm:artistName: %(name)s*" . '.replace('\n', ' ').strip() % {'name': name}

        return Query.songs(query)
Beispiel #41
0
    "http://www.tracker-project.org/temp/nmm#Video": "videos",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SoftwareApplication": "software",
    "http://www.tracker-project.org/temp/nmm#Photo": "pictures",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Folder": "folders",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject": "files"
}

if __name__ == "__main__":
    results = {}
    conn = Tracker.SparqlConnection.get()
    words = sys.argv[1].split(" ");
    query_params = []
    for i in words:
        if i:
            if i[0] == '"' and i[-1] == '"':
                query_params.append("?s fts:match \"" + Tracker.sparql_escape_string(i[1:-1]) + "\"")
            else:
                query_params.append("?s fts:match \"" + Tracker.sparql_escape_string(i) + "*\"")
    query = """SELECT ?s nie:url(?s) nmm:musicAlbum(?s) nmm:performer(?s) nmm:trackNumber(?s) nie:title(?s) nie:mimeType(?s) rdf:type(?s)
                 WHERE { """ + " . ".join(query_params) + """ }
                 ORDER BY DESC (fts:rank(?s))
                 LIMIT 100""";
    cursor = conn.query(query)
    while cursor.next():
        defined_type = None;
        if not cursor.get_string(7)[0] or not cursor.get_string(1)[0]:
            #If we have no defined file type or no file url, skip
            continue
        result_types = cursor.get_string(7)[0].split(",")
        while len(result_types) > 0 and defined_type == None:
            t = result_types.pop()
Beispiel #42
0
    def songs(self, artist_name=None, album_name=None, track_name=None):
        '''Return all songs matching specific search criteria.

        These are grouped into their respective releases. Any tracks that
        aren't present on any releases will appear last. Any tracks that
        appear on multiple releases will appear multiple times.

        '''
        if artist_name:
            artist_id = self.artist_id(artist_name)
            artist_select = ""
            artist_pattern = """
                ?track nmm:performer <%s> .
            """ % artist_id
        else:
            artist_select = "nmm:artistName(nmm:performer(?track))"
            artist_pattern = ""
        if album_name:
            album_pattern = """
                ?album nie:title ?albumTitle .
                FILTER (LCASE(?albumTitle) = "%s")
            """  % Tracker.sparql_escape_string(album_name.lower())
        else:
            album_pattern = ""
        if track_name:
            track_pattern = """
                ?track nie:title ?trackTitle .
                FILTER (LCASE(?trackTitle) = "%s")
            """  % Tracker.sparql_escape_string(track_name.lower())
        else:
            track_pattern = ""

        query_songs_with_releases = """
        SELECT
            nie:url(?track)
            nmm:albumTitle(?album)
            nie:title(?track)
            %s
        WHERE {
            ?album a nmm:MusicAlbum .
            ?track a nmm:MusicPiece ;
                nmm:musicAlbum ?album .
            %s %s %s
        } ORDER BY
            nmm:albumTitle(?album)
            nmm:trackNumber(?track)
        """ % (artist_select, artist_pattern, album_pattern, track_pattern)

        songs_with_releases = self.query(query_songs_with_releases)

        if not album_name:
            query_songs_without_releases = """
            SELECT
                nie:url(?track)
                ?album
                nie:title(?track)
                %s
            WHERE {
                ?track a nmm:MusicPiece .
                %s %s
                OPTIONAL { ?track nmm:musicAlbum ?album }
                FILTER (! bound (?album))
            } ORDER BY
                %s
                nie:title(?track)
            """ % (artist_select, artist_pattern, track_pattern, artist_select)

            songs_without_releases = self.query(
                query_songs_without_releases)
        else:
            songs_without_releases = None

        result = []

        # The artist name may be returned as None if it's unknown to Tracker,
        # so we can't use None as an 'undefined' value. int(-1) will work,
        # as any artist named "-1" would be returned as str("-1").
        prev_artist_name = -1
        prev_album_name = -1

        album_tracks = []
        while songs_with_releases.next():
            if artist_select:
                artist_name = songs_with_releases.get_string(3)[0]
            album_name = songs_with_releases.get_string(1)[0]

            if prev_artist_name is -1:
                prev_artist_name = artist_name
            if prev_album_name is -1:
                prev_album_name = album_name

            if album_name != prev_album_name:
                yield {
                    'artist': prev_artist_name,
                    'album': prev_album_name,
                    'tracks': album_tracks,
                }
                album_tracks = []
                prev_artist_name = artist_name
                prev_album_name = album_name

            album_tracks.append({
                'track': songs_with_releases.get_string(2)[0],
                'location': songs_with_releases.get_string(0)[0]
            })
        if len(album_tracks) > 0:
            yield {
                'artist': artist_name,
                'album': album_name,
                'tracks': album_tracks,
            }

        prev_artist_name = -1
        catchall_tracks = []
        if songs_without_releases:
            while songs_without_releases.next():
                if artist_select:
                    artist_name = songs_without_releases.get_string(3)[0]
                if prev_artist_name is -1:
                    prev_artist_name = artist_name
                if prev_artist_name != artist_name:
                    yield {
                        'artist': prev_artist_name,
                        'tracks': catchall_tracks
                    }
                    prev_artist_name = artist_name
                    catchall_tracks = []
                catchall_tracks.append({
                    'track': songs_without_releases.get_string(2)[0],
                    'location': songs_without_releases.get_string(0)[0]
                })
            if len(catchall_tracks) > 0:
                yield {
                    'artist': artist_name,
                    'tracks': catchall_tracks
                }
Beispiel #43
0
class Query():
    music_folder = None
    MUSIC_URI = None
    download_folder = None
    DOWNLOAD_URI = None
    try:
        music_folder = GLib.get_user_special_dir(
            GLib.UserDirectory.DIRECTORY_MUSIC)
        MUSIC_URI = Tracker.sparql_escape_string(
            GLib.filename_to_uri(music_folder))
        download_folder = GLib.get_user_special_dir(
            GLib.UserDirectory.DIRECTORY_DOWNLOAD)
        DOWNLOAD_URI = Tracker.sparql_escape_string(
            GLib.filename_to_uri(download_folder))

        for folder in [music_folder, download_folder]:
            if os.path.islink(folder):
                logger.warn("%s is a symlink, this folder will be omitted" %
                            folder)
            else:
                i = len(next(os.walk(folder))[2])
                logger.debug("Found %d files in %s" % (i, folder))
    except TypeError:
        logger.warn("XDG user dirs are not set")

    @staticmethod
    def order_by_statement(attr):
        """Returns a SPARQL ORDER BY statement sorting by the given attribute, ignoring
            articles as defined in _("the"). 'Attr' should be given without parentheses,
            e.g., "attr='?author'"."""
        return_statement = "fn:lower-case(%(attribute)s)" % {'attribute': attr}
        # TRANSLATORS: _("the") should be a space-separated list of all-lowercase articles
        # (such as 'the') that should be ignored when alphabetizing artists/albums. This
        # list should include 'the' regardless of language. If some articles occur more
        # frequently than others, most common should appear first, least common last.
        for article in reversed(_("the a an").split(" ")):
            return_statement = '''IF(fn:starts-with(fn:lower-case(%(attribute)s), "%(article)s"),
            fn:substring(fn:lower-case(%(attribute)s), %(substr_start)s),
            %(nested_if)s)''' % {
                'attribute': attr,
                'article': article + " ",
                'substr_start': str(len(article) + 2),
                'nested_if': return_statement
            }
        return return_statement

    @staticmethod
    def all_albums():
        return Query.albums('?album a nmm:MusicAlbum .')

    @staticmethod
    def all_artists():
        return Query.artists('?album a nmm:MusicAlbum .')

    @staticmethod
    def all_songs():
        return Query.songs('?song a nmm:MusicPiece ; a nfo:FileDataObject .')

    @staticmethod
    def all_playlists():
        return Query.playlists('?playlist a nmm:Playlist .')

    @staticmethod
    def all_songs_count():
        query = '''
    SELECT
        COUNT(?song) AS childcount
    WHERE {
        ?song a nmm:MusicPiece ;
              a nfo:FileDataObject
        FILTER (
            tracker:uri-is-descendant(
                '%(music_dir)s', nie:url(?song)
            ) ||
            tracker:uri-is-descendant(
                '%(download_dir)s', nie:url(?song)
            )
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    '''.replace('\n', ' ').strip() % {
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def albums(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
        tracker:coalesce(
            (
                SELECT
                    GROUP_CONCAT(
                        nmm:artistName(?artist),
                        ','
                    )
                WHERE {
                    ?album nmm:albumArtist ?artist
                }
            ),
            (
                SELECT
                    GROUP_CONCAT(
                        (
                            SELECT
                                nmm:artistName(nmm:performer(?_12)) AS perf
                            WHERE {
                                ?_12 nmm:musicAlbum ?album
                            }
                            GROUP BY ?perf
                        ),
                        ','
                    ) AS album_performer
                WHERE {
                }
            )
        ) AS author
        xsd:integer(
            tracker:coalesce(
                nmm:albumTrackCount(?album),
                (
                    SELECT
                        COUNT(?_1)
                    WHERE {
                        ?_1 nmm:musicAlbum ?album ;
                            tracker:available 'true'
                        FILTER (
                            tracker:uri-is-descendant(
                                '%(music_dir)s', nie:url(?_1)
                            ) ||
                            tracker:uri-is-descendant(
                                '%(download_dir)s', nie:url(?_1)
                            )
                        )
                        FILTER (
                            NOT EXISTS {
                                ?_1 a nmm:Video
                            } &&
                            NOT EXISTS {
                                ?_1 a nmm:Playlist
                            }
                        )
                    }
                )
            )
        ) AS childcount
        (
            SELECT
                fn:year-from-dateTime(?c)
            WHERE {
                ?_2 nmm:musicAlbum ?album ;
                    nie:contentCreated ?c ;
                    tracker:available 'true'
                FILTER (
                    tracker:uri-is-descendant(
                        '%(music_dir)s', nie:url(?_2)
                    ) ||
                    tracker:uri-is-descendant(
                        '%(download_dir)s', nie:url(?_2)
                    )
                )
                FILTER (
                    NOT EXISTS {
                        ?_2 a nmm:Video
                    } &&
                    NOT EXISTS {
                        ?_2 a nmm:Playlist
                    }
                )
            }
            LIMIT 1
        ) AS creation-date
        {
            %(where_clause)s
            FILTER (
                EXISTS {
                    ?_3 nmm:musicAlbum ?album ;
                        tracker:available 'true'
                    FILTER (
                        tracker:uri-is-descendant(
                            '%(music_dir)s', nie:url(?_3)
                        ) ||
                        tracker:uri-is-descendant(
                            '%(download_dir)s', nie:url(?_3)
                        )
                    )
                    FILTER (
                        NOT EXISTS {
                            ?_3 a nmm:Video
                        } &&
                        NOT EXISTS {
                            ?_3 a nmm:Playlist
                        }
                    )
                }
            )
        }
    ORDER BY %(album_order)s
        %(artist_order)s
        ?albumyear
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI,
            'album_order': Query.order_by_statement("?title"),
            'artist_order': Query.order_by_statement("?author")
        }

        return query

    @staticmethod
    def artists(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
        tracker:coalesce(
            (
                SELECT
                    GROUP_CONCAT(
                        nmm:artistName(?artist),
                        ','
                    )
                WHERE {
                    ?album nmm:albumArtist ?artist
                }
            ),
            (
                SELECT
                    GROUP_CONCAT(
                        (
                            SELECT
                                nmm:artistName(nmm:performer(?_12)) AS perf
                            WHERE {
                                ?_12 nmm:musicAlbum ?album
                                FILTER (
                                    tracker:uri-is-descendant(
                                        '%(music_dir)s', nie:url(?_12)
                                    ) ||
                                    tracker:uri-is-descendant(
                                        '%(download_dir)s', nie:url(?_12)
                                    )
                                )
                                FILTER (
                                    NOT EXISTS {
                                        ?_12 a nmm:Video
                                    } &&
                                    NOT EXISTS {
                                        ?_12 a nmm:Playlist
                                    }
                                )
                            }
                            GROUP BY ?perf
                        ),
                        ','
                    ) AS album_performer
                WHERE {
                }
            )
        ) AS author
        xsd:integer(
            tracker:coalesce(
                nmm:albumTrackCount(?album),
                (
                    SELECT
                        COUNT(?_1)
                    WHERE {
                        ?_1 nmm:musicAlbum ?album ;
                        tracker:available 'true'
                        FILTER (
                            tracker:uri-is-descendant(
                                '%(music_dir)s', nie:url(?_1)
                            ) ||
                            tracker:uri-is-descendant(
                                '%(download_dir)s', nie:url(?_1)
                            )
                        )
                        FILTER (
                            NOT EXISTS {
                                ?_1 a nmm:Video
                            } &&
                            NOT EXISTS {
                                ?_1 a nmm:Playlist
                            }
                        )
                    }
                )
            )
        ) AS childcount
        (
            SELECT
                fn:year-from-dateTime(?c)
            WHERE {
                ?_2 nmm:musicAlbum ?album ;
                    nie:contentCreated ?c ;
                    tracker:available 'true'
                FILTER (
                    tracker:uri-is-descendant(
                        '%(music_dir)s', nie:url(?_2)
                    ) ||
                    tracker:uri-is-descendant(
                        '%(download_dir)s', nie:url(?_2)
                    )
                )
                FILTER (
                    NOT EXISTS {
                        ?_2 a nmm:Video
                    } &&
                    NOT EXISTS {
                        ?_2 a nmm:Playlist
                    }
                )
            }
            LIMIT 1
        ) AS creation-date
        {
            %(where_clause)s
            FILTER (
                EXISTS {
                    ?_3 nmm:musicAlbum ?album ;
                        tracker:available 'true'
                    FILTER (
                        tracker:uri-is-descendant(
                            '%(music_dir)s', nie:url(?_3)
                        ) ||
                        tracker:uri-is-descendant(
                            '%(download_dir)s', nie:url(?_3)
                        )
                    )
                    FILTER (
                        NOT EXISTS {
                            ?_3 a nmm:Video
                        } &&
                        NOT EXISTS {
                            ?_3 a nmm:Playlist
                        }
                    )
                }
            )
        }
    ORDER BY %(artist_order)s
        ?albumyear
        %(album_order)s
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI,
            'artist_order': Query.order_by_statement("?author"),
            'album_order': Query.order_by_statement("nie:title(?album)")
        }

        return query

    @staticmethod
    def songs(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?song)
        tracker:id(?song) AS id
        nie:url(?song) AS url
        nie:title(?song) AS title
        nmm:artistName(nmm:performer(?song)) AS artist
        nie:title(nmm:musicAlbum(?song)) AS album
        nfo:duration(?song) AS duration
        IF(bound(?tag), 'truth!', '') AS lyrics
        {
            %(where_clause)s
            OPTIONAL {
                ?song nao:hasTag ?tag .
                FILTER( ?tag = nao:predefined-tag-favorite )
            }
            FILTER (
                tracker:uri-is-descendant(
                    '%(music_dir)s', nie:url(?song)
                ) ||
                tracker:uri-is-descendant(
                    '%(download_dir)s', nie:url(?song)
                )
            )
            FILTER (
                NOT EXISTS {
                    ?song a nmm:Video
                } &&
                NOT EXISTS {
                    ?song a nmm:Playlist
                }
            )
        }
    ORDER BY tracker:added(?song)
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def playlists(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?playlist)
        tracker:id(?playlist) AS id
        nie:title(?playlist) AS title
        nfo:entryCounter(?playlist) AS childcount
        {
            %(where_clause)s
            OPTIONAL {
                ?playlist a nfo:FileDataObject .
                FILTER (
                    EXISTS {
                        ?playlist tracker:available 'true'
                        FILTER (
                            tracker:uri-is-descendant(
                                '%(music_dir)s', nie:url(?playlist)
                            ) ||
                            tracker:uri-is-descendant(
                                '%(download_dir)s', nie:url(?playlist)
                            )
                        )
                    }
                )
            }
        }
    ORDER BY fn:lower-case(?title)
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def album_songs(album_id):
        query = '''
    SELECT DISTINCT
        rdf:type(?song)
        tracker:id(?song) AS id
        nie:url(?song) AS url
        nie:title(?song) AS title
        nmm:artistName(nmm:performer(?song)) AS artist
        nie:title(nmm:musicAlbum(?song)) AS album
        nfo:duration(?song) AS duration
        IF(bound(?tag), 'truth!', '') AS lyrics
    WHERE {
        ?song a nmm:MusicPiece ;
              a nfo:FileDataObject ;
              nmm:musicAlbum ?album .
        OPTIONAL {
            ?song nao:hasTag ?tag .
            FILTER( ?tag = nao:predefined-tag-favorite )
        }
        FILTER (
            tracker:id(?album) = %(album_id)s
        )
        FILTER (
            tracker:uri-is-descendant(
                '%(music_dir)s', nie:url(?song)
            ) ||
            tracker:uri-is-descendant(
                '%(download_dir)s', nie:url(?song)
            )
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    ORDER BY
         nmm:setNumber(nmm:musicAlbumDisc(?song))
         nmm:trackNumber(?song)
         tracker:added(?song)
    '''.replace('\n', ' ').strip() % {
            'album_id': album_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def playlist_songs(playlist_id, filter_clause=None):
        query = '''
    SELECT
        rdf:type(?song)
        tracker:id(?entry) AS id
        nie:url(?song) AS url
        nie:title(?song) AS title
        nmm:artistName(nmm:performer(?song)) AS artist
        nie:title(nmm:musicAlbum(?song)) AS album
        nfo:duration(?song) AS duration
        IF(bound(?tag), 'truth!', '') AS lyrics
    WHERE {
        ?playlist a nmm:Playlist ;
            a nfo:MediaList ;
            nfo:hasMediaFileListEntry ?entry .
        ?entry a nfo:MediaFileListEntry ;
            nfo:entryUrl ?url .
        ?song a nmm:MusicPiece ;
             a nfo:FileDataObject ;
             nie:url ?url .
        OPTIONAL {
            ?song nao:hasTag ?tag .
            FILTER( ?tag = nao:predefined-tag-favorite )
        }
        FILTER (
            %(filter_clause)s
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    ORDER BY
         nfo:listPosition(?entry)
    '''.replace('\n', ' ').strip() % {
            'playlist_id': playlist_id,
            'filter_clause': filter_clause
            or 'tracker:id(?playlist) = ' + playlist_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def get_album_for_album_id(album_id):
        query = """
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
    WHERE {
        ?album a nmm:MusicAlbum  .
        FILTER (
            tracker:id(?album) = %(album_id)s
        )
    }
    """.replace("\n", " ").strip() % {
            'album_id': album_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }
        return query

    @staticmethod
    def get_album_for_song_id(song_id):
        query = """
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
    WHERE {
        ?song a nmm:MusicPiece ;
              nmm:musicAlbum ?album .
        FILTER (
            tracker:id(?song) = %(song_id)s
        )
        FILTER (
            tracker:uri-is-descendant(
                '%(music_dir)s', nie:url(?song)
            ) ||
            tracker:uri-is-descendant(
                '%(download_dir)s', nie:url(?song)
            )
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    """.replace("\n", " ").strip() % {
            'song_id': song_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }
        return query

    @staticmethod
    def update_playcount(song_url):
        query = """
    INSERT OR REPLACE { ?song nie:usageCounter ?playcount . }
    WHERE {
        SELECT
            IF(bound(?usage), (?usage + 1), 1) AS playcount
            ?song
            WHERE {
                ?song a nmm:MusicPiece .
                OPTIONAL { ?song nie:usageCounter ?usage . }
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        }
    """.replace("\n", " ").strip() % {
            'song_url': song_url
        }

        return query

    @staticmethod
    def update_last_played(song_url, time):
        query = """
    INSERT OR REPLACE { ?song nfo:fileLastAccessed '%(time)s' . }
    WHERE {
        SELECT
            ?song
            WHERE {
                ?song a nmm:MusicPiece .
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        }
    """.replace("\n", " ").strip() % {
            'song_url': song_url,
            'time': time
        }

        return query

    @staticmethod
    def create_playlist(title):
        query = """
    INSERT {
        _:playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nie:title "%(title)s" ;
            nfo:entryCounter 0 .
    }
    """.replace("\n", " ").strip() % {
            'title': title
        }
        return query

    @staticmethod
    def create_tag(tag_text):
        query = """
    INSERT OR REPLACE {
        _:tag
            a nao:Tag ;
            rdfs:comment '%(tag_text)s'.
    }
    """.replace("\n", " ").strip() % {
            'tag_text': tag_text
        }
        return query

    @staticmethod
    def create_playlist_with_tag(title, tag_text):
        # TODO: make this an extension of 'create playlist' rather than its own func.?
        # TODO: CREATE TAG IF IT DOESN'T EXIST!
        query = """
    INSERT {
        _:playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nie:title "%(title)s" ;
            nfo:entryCounter 0 ;
            nao:hasTag ?tag.
    }
    WHERE {
        SELECT ?tag
        WHERE {
            ?tag a nao:Tag ;
                rdfs:comment '%(tag_text)s'.
        }
    }
    """.replace("\n", " ").strip() % {
            'title': title,
            'tag_text': tag_text
        }
        return query

    @staticmethod
    def delete_playlist(playlist_id):
        query = """
    DELETE {
        ?playlist
            a rdfs:Resource .
        ?entry
            a rdfs:Resource .
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList .
        OPTIONAL {
            ?playlist
                nfo:hasMediaFileListEntry ?entry .
        }
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s
        )
    }
    """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id
        }
        return query

    @staticmethod
    def add_song_to_playlist(playlist_id, song_uri):
        query = """
    INSERT OR REPLACE {
        _:entry
            a nfo:MediaFileListEntry ;
            nfo:entryUrl "%(song_uri)s" ;
            nfo:listPosition ?position .
        ?playlist
            nfo:entryCounter ?position ;
            nfo:hasMediaFileListEntry _:entry .
    }
    WHERE {
        SELECT
            ?playlist
            (?counter + 1) AS position
        WHERE {
            ?playlist
                a nmm:Playlist ;
                a nfo:MediaList ;
                nfo:entryCounter ?counter .
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
    }
    """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id,
            'song_uri': song_uri
        }
        return query

    @staticmethod
    def remove_song_from_playlist(playlist_id, song_id):
        query = """
    INSERT OR REPLACE {
        ?entry
            nfo:listPosition ?position .
    }
    WHERE {
        SELECT
            ?entry
            (?old_position - 1) AS position
        WHERE {
            ?entry
                a nfo:MediaFileListEntry ;
                nfo:listPosition ?old_position .
            ?playlist
                nfo:hasMediaFileListEntry ?entry .
            FILTER (?old_position > ?removed_position)
            {
                SELECT
                    ?playlist
                    ?removed_position
                WHERE {
                    ?playlist
                        a nmm:Playlist ;
                        a nfo:MediaList ;
                        nfo:hasMediaFileListEntry ?removed_entry .
                    ?removed_entry
                        nfo:listPosition ?removed_position .
                    FILTER (
                        tracker:id(?playlist) = %(playlist_id)s &&
                        tracker:id(?removed_entry) = %(song_id)s
                    )
                }
            }
        }
    }
    INSERT OR REPLACE {
        ?playlist
            nfo:entryCounter ?new_counter .
    }
    WHERE {
        SELECT
            ?playlist
            (?counter - 1) AS new_counter
        WHERE {
            ?playlist
                a nmm:Playlist ;
                a nfo:MediaList ;
                nfo:entryCounter ?counter .
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
    }
    DELETE {
        ?playlist
            nfo:hasMediaFileListEntry ?entry .
        ?entry
            a rdfs:Resource .
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nfo:hasMediaFileListEntry ?entry .
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s &&
            tracker:id(?entry) = %(song_id)s
        )
    }
    """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id,
            'song_id': song_id
        }
        return query

    @staticmethod
    def get_playlist_with_id(playlist_id):
        query = """
    ?playlist a nmm:Playlist .
    FILTER (
        tracker:id(?playlist) = %(playlist_id)s
    )
    """.replace('\n', ' ').strip() % {
            'playlist_id': playlist_id
        }

        return Query.playlists(query)

    @staticmethod
    def get_playlist_with_tag(playlist_tag):
        query = """
    ?playlist
        a nmm:Playlist ;
        nao:hasTag ?tag .
    ?tag rdfs:comment ?tag_text .
    FILTER ( ?tag_text = '%(playlist_tag)s' )
    """.replace('\n', ' ').strip() % {
            'playlist_tag': playlist_tag
        }

        return Query.playlists(query)

    @staticmethod
    def get_playlist_with_urn(playlist_urn):
        query = """
    SELECT DISTINCT
        tracker:id(<%(playlist_urn)s>) AS id
    WHERE {
        <%(playlist_urn)s> a nmm:Playlist
    }
    """.replace('\n', ' ').strip() % {
            'playlist_urn': playlist_urn
        }
        return query

    @staticmethod
    def get_playlist_song_with_id(playlist_id, entry_id):
        return Query.playlist_songs(playlist_id,
                                    'tracker:id(?entry) = ' + str(entry_id))

    @staticmethod
    def get_playlist_song_with_urn(entry_urn):
        query = """
    SELECT DISTINCT
        tracker:id(<%(entry_urn)s>) AS id
    WHERE {
        <%(entry_urn)s> a nfo:MediaFileListEntry
    }
    """.replace('\n', ' ').strip() % {
            'entry_urn': entry_urn
        }
        return query

    @staticmethod
    def clear_playlist_with_id(playlist_id):
        query = """
        DELETE {
            ?playlist
                nfo:hasMediaFileListEntry ?entry .
            ?entry
                a rdfs:Resource .
        }
        WHERE {
            ?playlist
                a nmm:Playlist ;
                a nfo:MediaList ;
                nfo:hasMediaFileListEntry ?entry .
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
        """.replace('\n', ' ').strip() % {
            'playlist_id': playlist_id
        }

        return query

    @staticmethod
    def get_most_played_songs():
        # TODO: set playlist size somewhere? Currently default is 50.
        query = """
        SELECT ?url
        WHERE {
            ?song a nmm:MusicPiece ;
                nie:usageCounter ?count ;
                nie:isStoredAs ?as .
          ?as nie:url ?url .
        } ORDER BY DESC(?count) LIMIT 50
        """.replace('\n', ' ').strip()

        return query

    @staticmethod
    def get_never_played_songs():
        query = """
        SELECT ?url
        WHERE {
            ?song a nmm:MusicPiece ;
                nie:isStoredAs ?as .
            ?as nie:url ?url .
            FILTER ( NOT EXISTS { ?song nie:usageCounter ?count .} )
        } ORDER BY nfo:fileLastAccessed(?song)
        """.replace('\n', ' ').strip()

        return query

    def get_recently_played_songs():
        #TODO: or this could take comparison date as an argument so we don't need to make a date string in query.py...
        #TODO: set time interval somewhere? A settings file? (Default is maybe 2 weeks...?)

        days_difference = 7  # currently hardcoding time interval of 7 days
        seconds_difference = days_difference * SECONDS_PER_DAY
        compare_date = time.strftime(
            sparql_midnight_dateTime_format,
            time.gmtime(time.time() - seconds_difference))

        query = """
            SELECT ?url
            WHERE {
                ?song a nmm:MusicPiece ;
                    nie:isStoredAs ?as ;
                    nfo:fileLastAccessed ?last_played .
                ?as nie:url ?url .
                FILTER ( ?last_played > '%(compare_date)s'^^xsd:dateTime )
                FILTER ( EXISTS { ?song nie:usageCounter ?count .} )
            } ORDER BY DESC(?last_played)
            """.replace('\n', ' ').strip() % {
            'compare_date': compare_date
        }

        return query

    def get_recently_added_songs():
        #TODO: or this could take comparison date as an argument so we don't need to make a date string in query.py...
        #TODO: set time interval somewhere? A settings file? (Default is maybe 2 weeks...?)

        days_difference = 7  # currently hardcoding time interval of 7 days
        seconds_difference = days_difference * SECONDS_PER_DAY
        compare_date = time.strftime(
            sparql_midnight_dateTime_format,
            time.gmtime(time.time() - seconds_difference))

        query = """
        SELECT ?url
        WHERE {
            ?song a nmm:MusicPiece ;
                nie:isStoredAs ?as ;
                tracker:added ?added .
            ?as nie:url ?url .
            FILTER ( ?added > '%(compare_date)s'^^xsd:dateTime )
        } ORDER BY DESC(?added)
        """.replace('\n', ' ').strip() % {
            'compare_date': compare_date
        }

        return query

    def get_favorite_songs():
        query = """
    SELECT ?url
    WHERE {
        ?song a nmm:MusicPiece ;
            nie:isStoredAs ?as ;
            nao:hasTag nao:predefined-tag-favorite .
        ?as nie:url ?url .
    } ORDER BY DESC(tracker:added(?song))
    """.replace('\n', ' ').strip()

        return query

    # Functions for search
    # TODO: make those queries actually return something
    @staticmethod
    def get_albums_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_albums_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum ;
                        nmm:albumArtist ?artist .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(?artist)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_albums_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?album)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_albums_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_artists_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_artists_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum ;
                        nmm:albumArtist ?artist .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(?artist)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_artists_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?album)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_artists_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_songs_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def get_songs_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def get_songs_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def get_songs_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def clear_playlist(playlist_id):
        # TODO is there a way to do this with only one FILTER statement?

        query = """
    DELETE {
        ?playlist
            nfo:hasMediaFileListEntry ?entry .
        ?entry
            a rdfs:Resource .
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nfo:hasMediaFileListEntry ?entry .
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s
        )
    }
    INSERT OR REPLACE {
        ?playlist nfo:entryCounter '0'
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList .
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s
        )
    }
        """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id
        }

        return query

    def add_favorite(song_url):
        query = """
            INSERT {
                ?song nao:hasTag nao:predefined-tag-favorite
            }
            WHERE {
                ?song a nmm:MusicPiece .
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        """.replace("\n", " ").strip() % {
            'song_url': song_url
        }

        return query

    def remove_favorite(song_url):
        query = """
            DELETE {
                ?song nao:hasTag nao:predefined-tag-favorite
            }
            WHERE {
                ?song a nmm:MusicPiece .
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        """.replace("\n", " ").strip() % {
            'song_url': song_url
        }

        return query
#!/usr/bin/python3

import gi, sys
from gi.repository import GLib, Gio, Tracker

try:
    connection = Tracker.SparqlConnection.new(
        Tracker.SparqlConnectionFlags.NONE,
        None,  # Database location, None creates it in-memory
        Tracker.sparql_get_ontology_nepomuk(),  # Ontology location
        None)

    # Create a resource containing RDF data
    resource = Tracker.Resource.new(None)
    resource.set_uri('rdf:type', 'nmm:MusicPiece')

    # Create a batch, and add the resource to it
    batch = connection.create_batch()
    batch.add_resource(None, resource)

    # Execute the batch to insert the data
    batch.execute()

    connection.close()

except Exception as e:
    print('Error: {0}'.format(e))
    sys.exit(-1)
Beispiel #45
0
    "http://www.tracker-project.org/temp/nmm#Video": "videos",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SoftwareApplication": "software",
    "http://www.tracker-project.org/temp/nmm#Photo": "pictures",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Folder": "folders",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject": "files"
}

if __name__ == "__main__":
    results = {}
    conn = Tracker.SparqlConnection.get()
    words = sys.argv[1].split(" ")
    query_params = []
    for i in words:
        if i:
            if i[0] == '"' and i[-1] == '"':
                query_params.append("?s fts:match \"" + Tracker.sparql_escape_string(i[1:-1]) + "\"")
            else:
                query_params.append("?s fts:match \"" + Tracker.sparql_escape_string(i) + "*\"")
    query = """SELECT ?s nie:url(?s) nmm:musicAlbum(?s) nmm:performer(?s) nmm:trackNumber(?s) nie:title(?s) nie:mimeType(?s) rdf:type(?s)
                 WHERE { """ + " . ".join(query_params) + """ }
                 ORDER BY DESC (fts:rank(?s))
                 LIMIT 100"""
    cursor = conn.query(query)
    while cursor.next():
        defined_type = None
        if not cursor.get_string(7)[0] or not cursor.get_string(1)[0]:
            #If we have no defined file type or no file url, skip
            continue
        result_types = cursor.get_string(7)[0].split(",")
        while len(result_types) > 0 and defined_type == None:
            t = result_types.pop()
Beispiel #46
0
    def get_songs_with_album_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?song nmm:musicAlbum [ fts:match '%(name)s*' ] . """.replace('\n', ' ').strip() % {'name': name}

        return Query.songs(query)
Beispiel #47
0
    def get_artists_with_track_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?song fts:match '"nie:title" : %(name)s*' . """.replace('\n', ' ').strip() % {'name': name}

        return Query.artists(query)
Beispiel #48
0
    def get_artists_with_artist_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?performer fts:match '"nmm:artistName" : %(name)s*' . """.replace('\n', ' ').strip() % {'name': name}

        return Query.artists(query)
Beispiel #49
0
    def get_songs_with_track_match(name):
        name = Tracker.sparql_escape_string(name)
        query = '?song fts:match "nie:title: %(name)s*" . '.replace('\n', ' ').strip() % {'name': name}

        return Query.songs(query)
Beispiel #50
0
    def search(self, text):
        # FIXME: Searches are limited to not bog down the UI with
        # widget creation ({List,Flow}Box limitations). The limit is
        # arbitrarily set to 50 and set in the Tracker query. It should
        # be possible to set it through Grilo options instead. This
        # does not work as expected and needs further investigation.
        term = Tracker.sparql_escape_string(
            GLib.utf8_normalize(GLib.utf8_casefold(text, -1), -1,
                                GLib.NormalizeMode.NFKD))

        # Artist search

        query = """
        SELECT DISTINCT
            rdf:type(?artist)
            tracker:id(?artist) AS ?id
        WHERE {
            ?song a nmm:MusicPiece ;
                    nmm:musicAlbum ?album ;
                    nmm:performer ?artist .
            BIND(tracker:normalize(
                nmm:artistName(nmm:albumArtist(?album)), 'nfkd') AS ?match1) .
            BIND(tracker:normalize(
                nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
            BIND(tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
            FILTER (
                CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match1)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match1), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match2)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match2), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match4)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match4), "%(name)s")
            )
            %(location_filter)s
        }
        LIMIT 50
        """.replace('\n', ' ').strip() % {
            'location_filter': self._location_filter(),
            'name': term
        }

        artist_filter_ids = []

        def artist_filter(coreartist):
            return coreartist.media.get_id() in artist_filter_ids

        def artist_search_cb(source, op_id, media, data, error):
            if error:
                print("ERROR", error)
                return

            if not media:
                self._artist_search_model.set_filter_func(artist_filter)
                return

            artist_filter_ids.append(media.get_id())

        options = self._fast_options.copy()
        self._source.query(query, self.METADATA_KEYS, options,
                           artist_search_cb)

        # Album search

        query = """
        SELECT DISTINCT
            rdf:type(nmm:musicAlbum(?song))
            tracker:id(nmm:musicAlbum(?song)) AS ?id
        WHERE {
            ?song a nmm:MusicPiece .
            BIND(tracker:normalize(
                nie:title(nmm:musicAlbum(?song)), 'nfkd') AS ?match1) .
            BIND(tracker:normalize(
                nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
            BIND(tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
            FILTER (
                CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match1)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match1), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match2)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match2), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match4)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match4), "%(name)s")
            )
            %(location_filter)s
        }
        LIMIT 50
        """.replace('\n', ' ').strip() % {
            'location_filter': self._location_filter(),
            'name': term
        }

        album_filter_ids = []

        def album_filter(corealbum):
            return corealbum.media.get_id() in album_filter_ids

        def albums_search_cb(source, op_id, media, data, error):
            if error:
                print("ERROR", error)
                return

            if not media:
                self._album_search_model.set_filter_func(album_filter)
                return

            album_filter_ids.append(media.get_id())

        options = self._fast_options.copy()
        self._source.query(query, self.METADATA_KEYS, options,
                           albums_search_cb)

        # Song search

        query = """
        SELECT DISTINCT
            rdf:type(?song)
            tracker:id(?song) AS ?id
        WHERE {
            ?song a nmm:MusicPiece .
            BIND(tracker:normalize(
                nie:title(nmm:musicAlbum(?song)), 'nfkd') AS ?match1) .
            BIND(tracker:normalize(
                nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
            BIND(tracker:normalize(
                nie:title(?song), 'nfkd') AS ?match3) .
            BIND(
                tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
            FILTER (
                CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match1)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match1), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match2)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match2), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match3)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match3), "%(name)s")
                || CONTAINS(tracker:case-fold(
                    tracker:unaccent(?match4)), "%(name)s")
                || CONTAINS(tracker:case-fold(?match4), "%(name)s")
            )
            %(location_filter)s
        }
        LIMIT 50
        """.replace('\n', ' ').strip() % {
            'location_filter': self._location_filter(),
            'name': term
        }

        filter_ids = []

        def songs_filter(coresong):
            return coresong.media.get_id() in filter_ids

        def songs_search_cb(source, op_id, media, data, error):
            if error:
                print("ERROR", error)
                return

            if not media:
                self._song_search_tracker.set_filter_func(songs_filter)
                return

            filter_ids.append(media.get_id())

        options = self._fast_options.copy()

        self._source.query(query, self.METADATA_KEYS, options, songs_search_cb)
Beispiel #51
0
    def get_artists_with_album_match(name):
        name = Tracker.sparql_escape_string(name)
        query = '?album fts:match "nie:title: %(name)s*" . '.replace('\n', ' ').strip() % {'name': name}

        return Query.artists(query)
Beispiel #52
0
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Folder":
    "folders",
    "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject":
    "files"
}

if __name__ == "__main__":
    results = {}
    conn = Tracker.SparqlConnection.get()
    words = sys.argv[1].split(" ")
    query_params = []
    for i in words:
        if i:
            if i[0] == '"' and i[-1] == '"':
                query_params.append("?s fts:match \"" +
                                    Tracker.sparql_escape_string(i[1:-1]) +
                                    "\"")
            else:
                query_params.append("?s fts:match \"" +
                                    Tracker.sparql_escape_string(i) + "*\"")
    query = """SELECT ?s nie:url(?s) nmm:musicAlbum(?s) nmm:performer(?s) nmm:trackNumber(?s) nie:title(?s) nie:mimeType(?s) rdf:type(?s)
                 WHERE { """ + " . ".join(query_params) + """ }
                 ORDER BY DESC (fts:rank(?s))
                 LIMIT 100"""
    cursor = conn.query(query)
    while cursor.next():
        defined_type = None
        if not cursor.get_string(7)[0] or not cursor.get_string(1)[0]:
            #If we have no defined file type or no file url, skip
            continue
        result_types = cursor.get_string(7)[0].split(",")
Beispiel #53
0
    def get_songs_with_album_match(name):
        name = Tracker.sparql_escape_string(name)
        query = """?album fts:match '"nie:title" : %(name)s*' . """.replace('\n', ' ').strip() % {'name': name}

        return Query.songs(query)