<commit_before>#!/usr/bin/env python
"""
Pyrana -- a minimalist music player.

This little script was written out of frustration with larger music
players. Pretty much all I've ever wanted out of a music player was one that
played random albums by picking a random artist, then picking a random album,
then playing that album, then picking _another random artist_.

For some reason,I've never run into a music player that played random albums
that way, which led to me often ending up having to skip past multiple Frank
Zappa albums when playing random albums. I like Zappa, but not that goddamned
much. Same deal with Slayer and Aphex Twin and Bad Religion, and all these other
artists and bands that I have discographies of.

Another problem I've had is that a lot of 'modern' music players base their
artist and album information off of metadata. I have a couple of issues with this:

1: My music collection is large. Doing a scan of metadata, even if it only needs
to be done once takes a long time. I hate it.

2: My music collection has unreliable metadata. This is because I'm a lazy
asshole, and haven't kept up with fixing metadata on music that I
download. That's right, I download music -- so do you, shut up. Since my music
collection is so large that the probability of me fixing the metadata ever is
basically nil. I can, however, rely on the directory structure of my music
collection.

This little ~50 line does one thing, and does it acceptably -- play random
albums from a music collection. Maybe it'll expand in the future. I doubt it.
"""
import os
import random
import time
import ConfigParser
import pygame.mixer as mixer

import pygtk
pygtk.require('2.0')
import gtk

import pynotify
pynotify.init("Basics")

config = ConfigParser.ConfigParser()
config.read('pyrana.cfg')

def notify(songpath):
    to_display = "Playing: %s" % songpath
    if config.get('main', 'notification_type') == 'pynotify':
        n = pynotify.Notification("Pyrana", to_display)
        n.show()
    else:
        print to_display


def play(root, frequency=44100):
    #give us a list of sets of albums by artists, assuming the directory structure
    #Artists
    # Albums
    #  Songs
    #This is a little ugly, but whatever. 
    artists = [set([os.path.join(artist, album)
                   for album in os.listdir(artist)
                   if os.path.isdir(os.path.join(artist, album))])
              for artist in [os.path.join(root, artistname)
                             for artistname in os.listdir(root)
                             if os.path.isdir(os.path.join(root, artistname))]]

    #just in case we get some empty directories
    artists = filter(None, artists)

    while artists:
        if not mixer.get_init():
            break
        artist = random.choice(artists)

        #this ensures that we never play the same album twice
        albumpath = artist.pop()

        #hopefully, the tracks will be named in such a way that we can rely
        #on their names for ordering 
        album = sorted([os.path.join(albumpath, song)
                        for song in os.listdir(albumpath)
                        if song.endswith('mp3')])
        while album:
            if not mixer.get_init():
                break
            if not mixer.music.get_busy():
                songpath = album[0]
                album = album[1:]
                notify(songpath)
                mixer.music.load(songpath)
                mixer.music.play()
            else:
                #avoid eating cpu
                time.sleep(1)
                #allow this shit to flush...
                while gtk.events_pending():
                    gtk.main_iteration(False)


        artists = filter(None, artists)


class Pyrana(object):
    def __init__(self, root, frequency=44100):
        self.frequency = frequency
        self.statusIcon = gtk.StatusIcon()
        self.statusIcon.connect('activate', self.activate)
        self.root = root
        self.statusIcon.set_visible(True)
        self.statusIcon.set_tooltip("Pyrana!")
        self.statusIcon.set_from_file('stopped.png')
        gtk.main()
        
    def activate(self, widget, data=None):
        if not mixer.get_init():
            mixer.init(self.frequency)
            self.statusIcon.set_from_file('playing.png')
            play(self.root)

        else:
            mixer.quit()
            self.statusIcon.set_from_file('stopped.png')


        
if __name__ == '__main__':
    import sys
    player = Pyrana(sys.argv[1])
<commit_msg>Move play method into Pyrana class, update tooltip text to reflect currently playing song<commit_after>#!/usr/bin/env python
"""
Pyrana -- a minimalist music player.

This little script was written out of frustration with larger music
players. Pretty much all I've ever wanted out of a music player was one that
played random albums by picking a random artist, then picking a random album,
then playing that album, then picking _another random artist_.

For some reason,I've never run into a music player that played random albums
that way, which led to me often ending up having to skip past multiple Frank
Zappa albums when playing random albums. I like Zappa, but not that goddamned
much. Same deal with Slayer and Aphex Twin and Bad Religion, and all these other
artists and bands that I have discographies of.

Another problem I've had is that a lot of 'modern' music players base their
artist and album information off of metadata. I have a couple of issues with this:

1: My music collection is large. Doing a scan of metadata, even if it only needs
to be done once takes a long time. I hate it.

2: My music collection has unreliable metadata. This is because I'm a lazy
asshole, and haven't kept up with fixing metadata on music that I
download. That's right, I download music -- so do you, shut up. Since my music
collection is so large that the probability of me fixing the metadata ever is
basically nil. I can, however, rely on the directory structure of my music
collection.

This little ~50 line does one thing, and does it acceptably -- play random
albums from a music collection. Maybe it'll expand in the future. I doubt it.
"""
import os
import random
import time
import ConfigParser
import pygame.mixer as mixer

import pygtk
pygtk.require('2.0')
import gtk

import pynotify
pynotify.init("Basics")

config = ConfigParser.ConfigParser()
config.read('pyrana.cfg')

def notify(songpath):
    to_display = "Playing: %s" % songpath
    if config.get('main', 'notification_type') == 'pynotify':
        n = pynotify.Notification("Pyrana", to_display)
        n.show()
    else:
        print to_display




class Pyrana(object):
    def __init__(self, root, frequency=44100):
        self.frequency = frequency
        self.statusIcon = gtk.StatusIcon()
        self.statusIcon.connect('activate', self.activate)
        self.root = root
        self.statusIcon.set_visible(True)
        self.statusIcon.set_tooltip("Pyrana!")
        self.statusIcon.set_from_file('stopped.png')

        #give us a list of sets of albums by artists, assuming the directory structure
        #Artists
        # Albums
        #  Songs
        #This is a little ugly, but whatever. 
        self.artists = [set([os.path.join(artist, album)
                             for album in os.listdir(artist)
                             if os.path.isdir(os.path.join(artist, album))])
                        for artist in [os.path.join(root, artistname)
                                       for artistname in os.listdir(root)
                                       if os.path.isdir(os.path.join(root, artistname))]]

        #just in case we get some empty directories
        self.artists = filter(None, self.artists)

        gtk.main()
        
    def activate(self, widget, data=None):
        if not mixer.get_init():
            mixer.init(self.frequency)
            self.statusIcon.set_from_file('playing.png')
            self._play()


        else:
            mixer.quit()
            self.statusIcon.set_from_file('stopped.png')

    def _play(self):
        while self.artists:
            if not mixer.get_init():
                break
            artist = random.choice(self.artists)

            #this ensures that we never play the same album twice
            albumpath = artist.pop()

            #hopefully, the tracks will be named in such a way that we can rely
            #on their names for ordering 
            album = sorted([os.path.join(albumpath, song)
                            for song in os.listdir(albumpath)
                            if song.endswith('mp3')])
            while album:
                if not mixer.get_init():
                    break
                if not mixer.music.get_busy():
                    songpath = album[0]
                    album = album[1:]
                    notify(songpath)
                    self.statusIcon.set_tooltip("Playing: %s" % songpath)
                    mixer.music.load(songpath)
                    mixer.music.play()
                else:
                    #avoid eating cpu
                    time.sleep(1)
                    #allow this shit to flush...
                    while gtk.events_pending():
                        gtk.main_iteration(False)


            self.artists = filter(None, self.artists)
        
if __name__ == '__main__':
    import sys
    player = Pyrana(sys.argv[1])

{'fraction_non_alphanumeric': 0.07716802887166968, 'fraction_numerical': 0.003927396242437108, 'mean_word_length': 2.223400615805679, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 2, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '848936', 'n_tokens_mistral': 2654, 'n_tokens_neox': 2514, 'n_words': 989}