!c99Shell v. 1.0 pre-release build #16!

Software: Apache/2.2.3 (CentOS). PHP/5.1.6 

uname -a: Linux mx-ll-110-164-51-230.static.3bb.co.th 2.6.18-194.el5PAE #1 SMP Fri Apr 2 15:37:44
EDT 2010 i686
 

uid=48(apache) gid=48(apache) groups=48(apache) 

Safe-mode: OFF (not secure)

/usr/lib/rhythmbox/plugins/lyrics/   drwxr-xr-x
Free 51.94 GB of 127.8 GB (40.64%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     __init__.py (10.92 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*-
#
# Copyright (C) 2006 Jonathan Matthew
# Copyright (C) 2007 James Livingston
# Copyright (C) 2007 Sirio BolaƱos Puchet
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# The Rhythmbox authors hereby grants permission for non-GPL compatible
# GStreamer plugins to be used and distributed together with GStreamer
# and Rhythmbox. This permission is above and beyond the permissions granted
# by the GPL license by which Rhythmbox is covered. If you modify this code
# you may extend this exception to your version of the code, but you are not
# obligated to do so. If you do not wish to do so, delete this exception
# statement from your version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
#
# TODO:
# - check that the lyrics returned even remotely match the request?

import os, re
import gtk, gtk.glade
import gconf
import rhythmdb, rb

import LyricsParse
from LyricsConfigureDialog import LyricsConfigureDialog

ui_str = """
<ui>
  <menubar name="MenuBar">
    <menu name="ViewMenu" action="View">
      <menuitem name="ViewSongLyrics" action="ViewSongLyrics"/>
    </menu>
  </menubar>
</ui>
"""

LYRIC_TITLE_STRIP=["\(live[^\)]*\)", "\(acoustic[^\)]*\)", "\([^\)]*mix\)", "\([^\)]*version\)", "\([^\)]*edit\)", "\(feat[^\)]*\)"]
LYRIC_TITLE_REPLACE=[("/", "-"), (" & ", " and ")]
LYRIC_ARTIST_REPLACE=[("/", "-"), (" & ", " and ")]

gconf_keys = {    'engines' : '/apps/rhythmbox/plugins/lyrics/engines',
        'folder': '/apps/rhythmbox/plugins/lyrics/folder'
         }


def create_lyrics_view():
    tview = gtk.TextView()
    tview.set_wrap_mode(gtk.WRAP_WORD)
    tview.set_editable(False)
    tview.set_left_margin(6)

    tview.set_size_request (0, 0)
    sw = gtk.ScrolledWindow()
    sw.add(tview)
    sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
    sw.set_shadow_type(gtk.SHADOW_IN)

    vbox = gtk.VBox(spacing=12)
    vbox.pack_start(sw, expand=True)
    
    return (vbox, tview.get_buffer(), tview)

def parse_song_data(artist, title):
    
    # replace ampersands and the like
    for exp in LYRIC_ARTIST_REPLACE:
        artist = re.sub(exp[0], exp[1], artist)
    for exp in LYRIC_TITLE_REPLACE:
        title = re.sub(exp[0], exp[1], title)

    # strip things like "(live at Somewhere)", "(accoustic)", etc
    for exp in LYRIC_TITLE_STRIP:
        title = re.sub (exp, '', title)

    # compress spaces
    title = title.strip()
    artist = artist.strip()    
    
    return (artist, title)
    
def build_cache_path(artist, title):
    folder = gconf.client_get_default().get_string(gconf_keys['folder'])
    if folder is None:
        folder = "~/.lyrics"

    lyrics_folder = os.path.expanduser (folder)
    if not os.path.exists (lyrics_folder):
        os.mkdir (lyrics_folder)

    artist_folder = lyrics_folder + '/' + artist[:128]
    if not os.path.exists (artist_folder):
        os.mkdir (artist_folder)

    return artist_folder + '/' + title[:128] + '.lyric'

class LyricGrabber(object):
    def __init__(self, db, entry):
        self.loader = rb.Loader ()
        self.db = db
        self.entry = entry
        
        self.artist = self.db.entry_get(self.entry, rhythmdb.PROP_ARTIST).lower()
        self.title = self.db.entry_get(self.entry, rhythmdb.PROP_TITLE).lower()

        (self.artist, self.title) = parse_song_data(self.artist, self.title)

        self.cache_path = build_cache_path(self.artist, self.title)

    def verify_lyric(self):
        return os.path.exists(self.cache_path)
      
    def search_lyrics(self, callback, cache_only=False):
        self.callback = callback
        
        status = self.verify_lyric()
        
        if status:
            self.loader.get_url(self.cache_path, callback)
        else:
            if cache_only:
                self.callback(_("No lyrics found"))
            else:
                def lyric_callback (text):
                    if text is not None:
                        f = file (self.cache_path, 'w')
                        f.write (text)
                        f.close ()
                        self.callback(text)
                    else:
                        self.callback(_("No lyrics found"))

                parser = LyricsParse.Parser(gconf_keys, self.artist, self.title)
                parser.get_lyrics(lyric_callback)

class LyricPane(object):
    def __init__(self, db, song_info):
        self.db = db
        self.song_info = song_info
        self.entry = self.song_info.get_property("current-entry")
        
        self.build_path()
        
        def save_lyrics(cache_path, text):
            f = file (cache_path, 'w')
            f.write (text)
            f.close ()
        
        def erase_lyrics(cache_path):
            f = file (cache_path, 'w')
            f.write ("")
            f.close ()
        
        def save_callback():
            buf = self.buffer
            startiter = buf.get_start_iter()
            enditer = buf.get_end_iter()
            text = buf.get_text(startiter, enditer)
            save_lyrics(self.cache_path, text)
            self.get_lyrics()
        
        def edit_callback(widget):
            if self.edit.get_active() == 1:
                self.tview.set_editable(True)
                self.edit.set_label(_("_Save"))
            else:
                if self.cache_path is not None:
                    save_callback()
                self.tview.set_editable(False)
                self.edit.set_label(_("_Edit"))

        def discard_callback(widget):
            if self.cache_path is not None and os.path.exists(self.cache_path):
                os.remove(self.cache_path)
            self.get_lyrics()
        
        def clear_callback(widget):
            if self.cache_path is not None and os.path.exists (self.cache_path):
                erase_lyrics(self.cache_path)
            self.get_lyrics()
       

        self.edit = gtk.ToggleButton(_("_Edit"))
        self.edit.connect('toggled', edit_callback)
        self.discard = gtk.Button(_("_Search again"))
        self.discard.connect('clicked', discard_callback)
        self.clear = gtk.Button(stock=gtk.STOCK_CLEAR)
        self.clear.connect('clicked', clear_callback)
        self.hbox = gtk.HButtonBox()
        self.hbox.set_spacing (6)
        self.hbox.set_layout(gtk.BUTTONBOX_END)
        self.hbox.add(self.edit)
        self.hbox.add(self.clear)
        self.hbox.add(self.discard)
        self.hbox.set_child_secondary (self.clear, is_secondary=True)

        (self.view, self.buffer, self.tview) = create_lyrics_view()

        self.view.pack_start(self.hbox, expand=False, fill=False, padding=6)
        self.view.set_spacing(2)
    
        self.view.show_all()
        self.page_num = song_info.append_page(_("Lyrics"), self.view)
        self.have_lyrics = 0
        self.visible = 0

        self.entry_change_id = song_info.connect('notify::current-entry', self.entry_changed)
        nb = self.view.get_parent()
        self.switch_page_id = nb.connect('switch-page', self.switch_page_cb)
        
        #self.get_lyrics()

    def build_path(self):

        artist = self.db.entry_get(self.entry, rhythmdb.PROP_ARTIST).lower()
        title = self.db.entry_get(self.entry, rhythmdb.PROP_TITLE).lower()
        (artist, title) = parse_song_data(artist, title)
        cache_path = build_cache_path(artist, title)
        self.cache_path = cache_path

    def entry_changed(self, pspec, duh):
        self.entry = self.song_info.get_property("current-entry")
        self.have_lyrics = 0
        if self.visible != 0:
            self.build_path()
            self.get_lyrics()

    def switch_page_cb(self, notebook, page, page_num):
        if self.have_lyrics != 0:
            return

        if page_num != self.page_num:
            self.visible = 0
            return

        self.visible = 1
        self.get_lyrics()

    def get_lyrics(self):
        if self.entry is None:
            return

        self.buffer.set_text(_("Searching for lyrics..."));
        lyrics_grabber = LyricGrabber(self.db, self.entry)
        lyrics_grabber.search_lyrics(self.buffer.set_text)
            

class LyricWindow (gtk.Window):

    def __init__(self):
        gtk.Window.__init__(self)
        self.set_border_width(12)

        close = gtk.Button(stock=gtk.STOCK_CLOSE)
        close.connect('clicked', lambda w: self.destroy())
    
        (lyrics_view, buffer, tview) = create_lyrics_view()
        self.buffer = buffer
        bbox = gtk.HButtonBox()
        bbox.set_layout(gtk.BUTTONBOX_END)
        bbox.pack_start(close)
        lyrics_view.pack_start(bbox, expand=False)
    
        self.add(lyrics_view)
        self.set_default_size(400, 300)
        self.show_all()

    def s_title(self, title, artist):
        self.set_title(title + " - " + artist + " - " + _("Lyrics"))

class LyricsDisplayPlugin(rb.Plugin):

    def __init__ (self):
        rb.Plugin.__init__ (self)
        self.window = None

    def activate (self, shell):
        self.shell = shell
        self.action = gtk.Action ('ViewSongLyrics', _('Song L_yrics'),
                      _('Display lyrics for the playing song'),
                      'rb-song-lyrics')
        self.activate_id = self.action.connect ('activate', self.show_song_lyrics, shell)
        
        self.action_group = gtk.ActionGroup ('SongLyricsPluginActions')
        self.action_group.add_action_with_accel (self.action, "<control>L")
        
        uim = shell.get_ui_manager ()
        uim.insert_action_group (self.action_group, 0)
        self.ui_id = uim.add_ui_from_string (ui_str)
        uim.ensure_update ()

        sp = shell.get_player ()
        self.pec_id = sp.connect('playing-song-changed', self.playing_entry_changed)
        self.current_entry = None
        self.playing_entry_changed (sp, sp.get_playing_entry ())

        self.csi_id = shell.connect('create_song_info', self.create_song_info)

    def deactivate (self, shell):
            
        uim = shell.get_ui_manager()
        uim.remove_ui (self.ui_id)
        uim.remove_action_group (self.action_group)

        self.action_group = None
        self.action = None

        sp = shell.get_player ()
        sp.disconnect (self.pec_id)
        shell.disconnect (self.csi_id)

        if self.window is not None:
            self.window.destroy ()
            self.window = None

    def create_configure_dialog(self, dialog=None):
        if not dialog:
            glade_file = self.find_file("lyrics-prefs.glade")
            dialog = LyricsConfigureDialog (glade_file, gconf_keys).get_dialog()
        dialog.present()
        return dialog
    
    def playing_entry_changed (self, sp, entry):
        if entry is not None:
            self.action.set_sensitive (True)
            self.update_song_lyrics(entry)
        else:
            self.action.set_sensitive (False)

    def update_song_lyrics(self, entry):
        if entry == self.current_entry:
            return
        
        db = self.shell.get_property ("db")
        
        if self.window is None:
            return

        title = db.entry_get(entry, rhythmdb.PROP_TITLE)
        artist = db.entry_get(entry, rhythmdb.PROP_ARTIST)

        self.window.s_title(title, artist)
        lyrics_grabber = LyricGrabber(db, entry)
        lyrics_grabber.search_lyrics(self.window.buffer.set_text)

    def show_song_lyrics (self, action, shell):

        if self.window is not None:
            self.window.destroy ()
            self.window = None

        db = shell.get_property ("db")
        sp = shell.get_player ()
        entry = sp.get_playing_entry ()

        if entry is None:
            return
        
        title = db.entry_get(entry, rhythmdb.PROP_TITLE)
        artist = db.entry_get(entry, rhythmdb.PROP_ARTIST)

        self.window = LyricWindow()
        self.window.s_title(title, artist)
        self.window.connect("destroy", self.window_deleted)
        lyrics_grabber = LyricGrabber(db, entry)
        lyrics_grabber.search_lyrics(self.window.buffer.set_text)

    def window_deleted (self, window):
        print "lyrics window destroyed"
        self.window = None
    
    def create_song_info (self, shell, song_info, is_multiple):

        if is_multiple is False:
            x = LyricPane(shell.get_property ("db"), song_info)

:: Command execute ::

Enter:
 
Select:
 

:: Shadow's tricks :D ::

Useful Commands
 
Warning. Kernel may be alerted using higher levels
Kernel Info:

:: Preddy's tricks :D ::

Php Safe-Mode Bypass (Read Files)

File:

eg: /etc/passwd

Php Safe-Mode Bypass (List Directories):

Dir:

eg: /etc/

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c999shell v. 1.0 pre-release build #16 Modded by Shadow & Preddy | RootShell Security Group | r57 c99 shell | Generation time: 0.0128 ]--