Conflicts:
	beets/library.py
This commit is contained in:
Rovanion Luckey 2014-10-05 13:17:21 +02:00
commit 60af550b18
85 changed files with 7042 additions and 2587 deletions

2
.gitignore vendored
View file

@ -6,6 +6,7 @@
.svn
.tox
.coverage
.idea
# file patterns
@ -22,6 +23,7 @@
*.project
*.pydevproject
*.ropeproject
*.orig
# Project Specific patterns

View file

@ -4,3 +4,4 @@
^MANIFEST$
^docs/_build/
^\.tox/
^\.idea/

View file

@ -12,7 +12,7 @@
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
__version__ = '1.3.8'
__version__ = '1.3.9'
__author__ = 'Adrian Sampson <adrian@radbox.org>'
import beets.library

View file

@ -65,10 +65,10 @@ def current_metadata(items):
fields = ['artist', 'album', 'albumartist', 'year', 'disctotal',
'mb_albumid', 'label', 'catalognum', 'country', 'media',
'albumdisambig']
for key in fields:
values = [getattr(item, key) for item in items if item]
likelies[key], freq = plurality(values)
consensus[key] = (freq == len(values))
for field in fields:
values = [item[field] for item in items if item]
likelies[field], freq = plurality(values)
consensus[field] = (freq == len(values))
# If there's an album artist consensus, use this for the artist.
if consensus['albumartist'] and likelies['albumartist']:
@ -261,16 +261,16 @@ def match_by_id(items):
# Is there a consensus on the MB album ID?
albumids = [item.mb_albumid for item in items if item.mb_albumid]
if not albumids:
log.debug('No album IDs found.')
log.debug(u'No album IDs found.')
return None
# If all album IDs are equal, look up the album.
if bool(reduce(lambda x, y: x if x == y else (), albumids)):
albumid = albumids[0]
log.debug('Searching for discovered album ID: ' + albumid)
log.debug(u'Searching for discovered album ID: {0}'.format(albumid))
return hooks.album_for_mbid(albumid)
else:
log.debug('No album ID consensus.')
log.debug(u'No album ID consensus.')
def _recommendation(results):
@ -330,7 +330,7 @@ def _add_candidate(items, results, info):
checking the track count, ordering the items, checking for
duplicates, and calculating the distance.
"""
log.debug('Candidate: %s - %s' % (info.artist, info.album))
log.debug(u'Candidate: {0} - {1}'.format(info.artist, info.album))
# Discard albums with zero tracks.
if not info.tracks:
@ -339,13 +339,13 @@ def _add_candidate(items, results, info):
# Don't duplicate.
if info.album_id in results:
log.debug('Duplicate.')
log.debug(u'Duplicate.')
return
# Discard matches without required tags.
for req_tag in config['match']['required'].as_str_seq():
if getattr(info, req_tag) is None:
log.debug('Ignored. Missing required tag: %s' % req_tag)
log.debug(u'Ignored. Missing required tag: {0}'.format(req_tag))
return
# Find mapping between the items and the track info.
@ -358,31 +358,36 @@ def _add_candidate(items, results, info):
penalties = [key for _, key in dist]
for penalty in config['match']['ignored'].as_str_seq():
if penalty in penalties:
log.debug('Ignored. Penalty: %s' % penalty)
log.debug(u'Ignored. Penalty: {0}'.format(penalty))
return
log.debug('Success. Distance: %f' % dist)
log.debug(u'Success. Distance: {0}'.format(dist))
results[info.album_id] = hooks.AlbumMatch(dist, info, mapping,
extra_items, extra_tracks)
def tag_album(items, search_artist=None, search_album=None,
search_id=None):
"""Bundles together the functionality used to infer tags for a
set of items comprised by an album. Returns everything relevant:
- The current artist.
- The current album.
- A list of AlbumMatch objects. The candidates are sorted by
distance (i.e., best match first).
- A :class:`Recommendation`.
If search_artist and search_album or search_id are provided, then
they are used as search terms in place of the current metadata.
"""Return a tuple of a artist name, an album name, a list of
`AlbumMatch` candidates from the metadata backend, and a
`Recommendation`.
The artist and album are the most common values of these fields
among `items`.
The `AlbumMatch` objects are generated by searching the metadata
backends. By default, the metadata of the items is used for the
search. This can be customized by setting the parameters. The
`mapping` field of the album has the matched `items` as keys.
The recommendation is calculated from the match qualitiy of the
candidates.
"""
# Get current metadata.
likelies, consensus = current_metadata(items)
cur_artist = likelies['artist']
cur_album = likelies['album']
log.debug('Tagging %s - %s' % (cur_artist, cur_album))
log.debug(u'Tagging {0} - {1}'.format(cur_artist, cur_album))
# The output result (distance, AlbumInfo) tuples (keyed by MB album
# ID).
@ -390,7 +395,7 @@ def tag_album(items, search_artist=None, search_album=None,
# Search by explicit ID.
if search_id is not None:
log.debug('Searching for album ID: ' + search_id)
log.debug(u'Searching for album ID: {0}'.format(search_id))
search_cands = hooks.albums_for_id(search_id)
# Use existing metadata or text search.
@ -400,32 +405,33 @@ def tag_album(items, search_artist=None, search_album=None,
if id_info:
_add_candidate(items, candidates, id_info)
rec = _recommendation(candidates.values())
log.debug('Album ID match recommendation is ' + str(rec))
log.debug(u'Album ID match recommendation is {0}'.format(str(rec)))
if candidates and not config['import']['timid']:
# If we have a very good MBID match, return immediately.
# Otherwise, this match will compete against metadata-based
# matches.
if rec == Recommendation.strong:
log.debug('ID match.')
log.debug(u'ID match.')
return cur_artist, cur_album, candidates.values(), rec
# Search terms.
if not (search_artist and search_album):
# No explicit search terms -- use current metadata.
search_artist, search_album = cur_artist, cur_album
log.debug(u'Search terms: %s - %s' % (search_artist, search_album))
log.debug(u'Search terms: {0} - {1}'.format(search_artist,
search_album))
# Is this album likely to be a "various artist" release?
va_likely = ((not consensus['artist']) or
(search_artist.lower() in VA_ARTISTS) or
any(item.comp for item in items))
log.debug(u'Album might be VA: %s' % str(va_likely))
log.debug(u'Album might be VA: {0}'.format(str(va_likely)))
# Get the results from the data sources.
search_cands = hooks.album_candidates(items, search_artist,
search_album, va_likely)
log.debug(u'Evaluating %i candidates.' % len(search_cands))
log.debug(u'Evaluating {0} candidates.'.format(len(search_cands)))
for info in search_cands:
_add_candidate(items, candidates, info)
@ -450,7 +456,7 @@ def tag_item(item, search_artist=None, search_title=None,
# First, try matching by MusicBrainz ID.
trackid = search_id or item.mb_trackid
if trackid:
log.debug('Searching for track ID: ' + trackid)
log.debug(u'Searching for track ID: {0}'.format(trackid))
for track_info in hooks.tracks_for_id(trackid):
dist = track_distance(item, track_info, incl_artist=True)
candidates[track_info.track_id] = \
@ -458,7 +464,7 @@ def tag_item(item, search_artist=None, search_title=None,
# If this is a good match, then don't keep searching.
rec = _recommendation(candidates.values())
if rec == Recommendation.strong and not config['import']['timid']:
log.debug('Track ID match.')
log.debug(u'Track ID match.')
return candidates.values(), rec
# If we're searching by ID, don't proceed.
@ -471,7 +477,8 @@ def tag_item(item, search_artist=None, search_title=None,
# Search terms.
if not (search_artist and search_title):
search_artist, search_title = item.artist, item.title
log.debug(u'Item search terms: %s - %s' % (search_artist, search_title))
log.debug(u'Item search terms: {0} - {1}'.format(search_artist,
search_title))
# Get and evaluate candidate metadata.
for track_info in hooks.item_candidates(item, search_artist, search_title):
@ -479,7 +486,7 @@ def tag_item(item, search_artist=None, search_title=None,
candidates[track_info.track_id] = hooks.TrackMatch(dist, track_info)
# Sort by distance and return with recommendation.
log.debug('Found %i candidates.' % len(candidates))
log.debug(u'Found {0} candidates.'.format(len(candidates)))
candidates = sorted(candidates.itervalues())
rec = _recommendation(candidates)
return candidates, rec

View file

@ -372,13 +372,13 @@ def album_for_id(releaseid):
"""
albumid = _parse_id(releaseid)
if not albumid:
log.debug('Invalid MBID (%s).' % (releaseid))
log.debug(u'Invalid MBID ({0}).'.format(releaseid))
return
try:
res = musicbrainzngs.get_release_by_id(albumid,
RELEASE_INCLUDES)
except musicbrainzngs.ResponseError:
log.debug('Album ID match failed.')
log.debug(u'Album ID match failed.')
return None
except musicbrainzngs.MusicBrainzError as exc:
raise MusicBrainzAPIError(exc, 'get release by ID', albumid,
@ -392,12 +392,12 @@ def track_for_id(releaseid):
"""
trackid = _parse_id(releaseid)
if not trackid:
log.debug('Invalid MBID (%s).' % (releaseid))
log.debug(u'Invalid MBID ({0}).'.format(releaseid))
return
try:
res = musicbrainzngs.get_recording_by_id(trackid, TRACK_INCLUDES)
except musicbrainzngs.ResponseError:
log.debug('Track ID match failed.')
log.debug(u'Track ID match failed.')
return None
except musicbrainzngs.MusicBrainzError as exc:
raise MusicBrainzAPIError(exc, 'get recording by ID', trackid,

View file

@ -56,8 +56,8 @@ list_format_item: $artist - $album - $title
list_format_album: $albumartist - $album
time_format: '%Y-%m-%d %H:%M:%S'
sort_album: smartartist+
sort_item: smartartist+
sort_album: albumartist+ album+
sort_item: artist+ album+ disc+ track+
paths:
default: $albumartist/$album%aunique{}/$track $title

View file

@ -20,5 +20,6 @@ from .query import Query, FieldQuery, MatchQuery, AndQuery, OrQuery
from .types import Type
from .queryparse import query_from_strings
from .queryparse import sort_from_strings
from .queryparse import parse_sorted_query
# flake8: noqa

View file

@ -24,8 +24,8 @@ import collections
import beets
from beets.util.functemplate import Template
from .query import MatchQuery, NullSort
from .types import BASE_TYPE
from beets.dbcore import types
from .query import MatchQuery, NullSort, TrueQuery
class FormattedMapping(collections.Mapping):
@ -115,11 +115,6 @@ class Model(object):
keys are field names and the values are `Type` objects.
"""
_bytes_keys = ()
"""Keys whose values should be stored as raw bytes blobs rather than
strings.
"""
_search_fields = ()
"""The fields that should be queried by default by unqualified query
terms.
@ -129,6 +124,11 @@ class Model(object):
"""Optional Types for non-fixed (i.e., flexible and computed) fields.
"""
_sorts = {}
"""Optional named sort criteria. The keys are strings and the values
are subclasses of `Sort`.
"""
@classmethod
def _getters(cls):
"""Return a mapping from field names to getter functions.
@ -160,21 +160,17 @@ class Model(object):
self.clear_dirty()
@classmethod
def _awaken(cls, db=None, fixed_values=None, flex_values=None):
def _awaken(cls, db=None, fixed_values={}, flex_values={}):
"""Create an object with values drawn from the database.
This is a performance optimization: the checks involved with
ordinary construction are bypassed.
"""
obj = cls(db)
if fixed_values:
for key, value in fixed_values.items():
obj._values_fixed[key] = cls._fields[key].normalize(value)
if flex_values:
for key, value in flex_values.items():
if key in cls._types:
value = cls._types[key].normalize(value)
obj._values_flex[key] = value
for key, value in fixed_values.iteritems():
obj._values_fixed[key] = cls._type(key).from_sql(value)
for key, value in flex_values.iteritems():
obj._values_flex[key] = cls._type(key).from_sql(value)
return obj
def __repr__(self):
@ -208,7 +204,7 @@ class Model(object):
If the field has no explicit type, it is given the base `Type`,
which does no conversion.
"""
return self._fields.get(key) or self._types.get(key) or BASE_TYPE
return self._fields.get(key) or self._types.get(key) or types.DEFAULT
def __getitem__(self, key):
"""Get the value for a field. Raise a KeyError if the field is
@ -332,19 +328,15 @@ class Model(object):
self._check_db()
# Build assignments for query.
assignments = ''
assignments = []
subvars = []
for key in self._fields:
if key != 'id' and key in self._dirty:
self._dirty.remove(key)
assignments += key + '=?,'
value = self[key]
# Wrap path strings in buffers so they get stored
# "in the raw".
if key in self._bytes_keys and isinstance(value, str):
value = buffer(value)
assignments.append(key + '=?')
value = self._type(key).to_sql(self[key])
subvars.append(value)
assignments = assignments[:-1] # Knock off last ,
assignments = ','.join(assignments)
with self._db.transaction() as tx:
# Main table update.
@ -737,7 +729,7 @@ class Database(object):
id INTEGER PRIMARY KEY,
entity_id INTEGER,
key TEXT,
value NONE,
value TEXT,
UNIQUE(entity_id, key) ON CONFLICT REPLACE);
CREATE INDEX IF NOT EXISTS {0}_by_entity
ON {0} (entity_id);
@ -745,14 +737,15 @@ class Database(object):
# Querying.
def _fetch(self, model_cls, query, sort=None):
def _fetch(self, model_cls, query=None, sort=None):
"""Fetch the objects of type `model_cls` matching the given
query. The query may be given as a string, string sequence, a
Query object, or None (to fetch everything). `sort` is an
optional Sort object.
`Sort` object.
"""
query = query or TrueQuery() # A null query.
sort = sort or NullSort() # Unsorted.
where, subvals = query.clause()
sort = sort or NullSort()
order_by = sort.order_clause()
sql = ("SELECT * FROM {0} WHERE {1} {2}").format(

View file

@ -18,10 +18,6 @@ import re
from operator import attrgetter
from beets import util
from datetime import datetime, timedelta
from collections import namedtuple
SortedQuery = namedtuple('SortedQuery', ['query', 'sort'])
class Query(object):
@ -87,6 +83,23 @@ class MatchQuery(FieldQuery):
return pattern == value
class NoneQuery(FieldQuery):
def __init__(self, field, fast=True):
self.field = field
self.fast = fast
def col_clause(self):
return self.field + " IS NULL", ()
@classmethod
def match(self, item):
try:
return item[self.field] is None
except KeyError:
return True
class StringFieldQuery(FieldQuery):
"""A FieldQuery that converts values to strings before matching
them.
@ -405,10 +418,14 @@ class Period(object):
return None
ordinal = string.count('-')
if ordinal >= len(cls.date_formats):
raise ValueError('date is not in one of the formats '
+ ', '.join(cls.date_formats))
# Too many components.
return None
date_format = cls.date_formats[ordinal]
date = datetime.strptime(string, date_format)
try:
date = datetime.strptime(string, date_format)
except ValueError:
# Parsing failed.
return None
precision = cls.precisions[ordinal]
return cls(date, precision)
@ -623,25 +640,6 @@ class FixedFieldSort(FieldSort):
return "{0} {1}".format(self.field, order)
class SmartArtistSort(Sort):
"""Sort by artist (either album artist or track artist),
prioritizing the sort field over the raw field.
"""
def __init__(self, model_cls, is_ascending=True):
self.model_cls = model_cls
self.is_ascending = is_ascending
def order_clause(self):
order = "ASC" if self.is_ascending else "DESC"
if 'albumartist' in self.model_cls._fields:
field = 'albumartist'
else:
field = 'artist'
return ('(CASE {0}_sort WHEN NULL THEN {0} '
'WHEN "" THEN {0} '
'ELSE {0}_sort END) {1}').format(field, order)
class SlowFieldSort(FieldSort):
"""A sort criterion by some model field other than a fixed field:
i.e., a computed or flexible field.
@ -654,6 +652,3 @@ class NullSort(Sort):
"""No sorting. Leave results unsorted."""
def sort(items):
return items
def __nonzero__(self):
return False

View file

@ -136,11 +136,10 @@ def construct_sort_part(model_cls, part):
assert direction in ('+', '-'), "part must end with + or -"
is_ascending = direction == '+'
if field in model_cls._fields:
if field in model_cls._sorts:
sort = model_cls._sorts[field](model_cls, is_ascending)
elif field in model_cls._fields:
sort = query.FixedFieldSort(field, is_ascending)
elif field == 'smartartist':
# Special case for smart artist sort.
sort = query.SmartArtistSort(model_cls, is_ascending)
else:
# Flexible or computed.
sort = query.SlowFieldSort(field, is_ascending)
@ -157,3 +156,25 @@ def sort_from_strings(model_cls, sort_parts):
for part in sort_parts:
sort.add_sort(construct_sort_part(model_cls, part))
return sort
def parse_sorted_query(model_cls, parts, prefixes={},
query_cls=query.AndQuery):
"""Given a list of strings, create the `Query` and `Sort` that they
represent.
"""
# Separate query token and sort token.
query_parts = []
sort_parts = []
for part in parts:
if part.endswith((u'+', u'-')) and u':' not in part:
sort_parts.append(part)
else:
query_parts.append(part)
# Parse each.
q = query_from_strings(
query_cls, model_cls, prefixes, query_parts
)
s = sort_from_strings(model_cls, sort_parts)
return q, s

View file

@ -34,30 +34,42 @@ class Type(object):
"""The `Query` subclass to be used when querying the field.
"""
null = None
"""The value to be exposed when the underlying value is None.
model_type = unicode
"""The Python type that is used to represent the value in the model.
The model is guaranteed to return a value of this type if the field
is accessed. To this end, the constructor is used by the `normalize`
and `from_sql` methods and the `default` property.
"""
@property
def null(self):
"""The value to be exposed when the underlying value is None.
"""
return self.model_type()
def format(self, value):
"""Given a value of this type, produce a Unicode string
representing the value. This is used in template evaluation.
"""
# Fallback formatter. Convert to Unicode at all cost.
if value is None:
return u''
elif isinstance(value, basestring):
if isinstance(value, bytes):
return value.decode('utf8', 'ignore')
else:
return value
else:
return unicode(value)
value = self.null
# `self.null` might be `None`
if value is None:
value = u''
if isinstance(value, bytes):
value = value.decode('utf8', 'ignore')
return unicode(value)
def parse(self, string):
"""Parse a (possibly human-written) string and return the
indicated value of this type.
"""
return string
try:
return self.model_type(string)
except ValueError:
return self.null
def normalize(self, value):
"""Given a value that will be assigned into a field of this
@ -67,26 +79,50 @@ class Type(object):
if value is None:
return self.null
else:
# TODO This should eventually be replaced by
# `self.model_type(value)`
return value
def from_sql(self, sql_value):
"""Receives the value stored in the SQL backend and return the
value to be stored in the model.
For fixed fields the type of `value` is determined by the column
type affinity given in the `sql` property and the SQL to Python
mapping of the database adapter. For more information see:
http://www.sqlite.org/datatype3.html
https://docs.python.org/2/library/sqlite3.html#sqlite-and-python-types
Flexible fields have the type afinity `TEXT`. This means the
`sql_value` is either a `buffer` or a `unicode` object` and the
method must handle these in addition.
"""
if isinstance(sql_value, buffer):
sql_value = bytes(sql_value).decode('utf8', 'ignore')
if isinstance(sql_value, unicode):
return self.parse(sql_value)
else:
return self.normalize(sql_value)
def to_sql(self, model_value):
"""Convert a value as stored in the model object to a value used
by the database adapter.
"""
return model_value
# Reusable types.
class Default(Type):
null = None
class Integer(Type):
"""A basic integer type.
"""
sql = u'INTEGER'
query = query.NumericQuery
null = 0
def format(self, value):
return unicode(value or 0)
def parse(self, string):
try:
return int(string)
except ValueError:
return 0
model_type = int
class PaddedInt(Integer):
@ -128,17 +164,11 @@ class Float(Type):
"""
sql = u'REAL'
query = query.NumericQuery
null = 0.0
model_type = float
def format(self, value):
return u'{0:.1f}'.format(value or 0.0)
def parse(self, string):
try:
return float(string)
except ValueError:
return 0.0
class NullFloat(Float):
"""Same as `Float`, but does not normalize `None` to `0.0`.
@ -151,13 +181,6 @@ class String(Type):
"""
sql = u'TEXT'
query = query.SubstringQuery
null = u''
def format(self, value):
return unicode(value) if value else u''
def parse(self, string):
return string
class Boolean(Type):
@ -165,7 +188,7 @@ class Boolean(Type):
"""
sql = u'INTEGER'
query = query.BooleanQuery
null = False
model_type = bool
def format(self, value):
return unicode(bool(value))
@ -175,7 +198,7 @@ class Boolean(Type):
# Shared instances of common types.
BASE_TYPE = Type()
DEFAULT = Default()
INTEGER = Integer()
PRIMARY_ID = Id(True)
FOREIGN_ID = Id(False)

View file

@ -81,7 +81,7 @@ def _save_state(state):
with open(config['statefile'].as_filename(), 'w') as f:
pickle.dump(state, f)
except IOError as exc:
log.error(u'state file could not be written: %s' % unicode(exc))
log.error(u'state file could not be written: {0}'.format(exc))
# Utilities for reading and writing the beets progress file, which
@ -278,10 +278,8 @@ class ImportSession(object):
# Split directory tasks into one task for each album
stages += [group_albums(self)]
if self.config['autotag']:
# Only look up and query the user when autotagging.
# FIXME We should also resolve duplicates when not
# autotagging.
# autotagging. This is currently handled in `user_query`
stages += [lookup_candidates(self), user_query(self)]
else:
stages += [import_asis(self)]
@ -339,7 +337,8 @@ class ImportSession(object):
# Either accept immediately or prompt for input to decide.
if self.want_resume is True or \
self.should_resume(toppath):
log.warn('Resuming interrupted import of %s' % toppath)
log.warn(u'Resuming interrupted import of {0}'.format(
util.displayable_path(toppath)))
self._is_resuming[toppath] = True
else:
# Clear progress; we're starting from the top.
@ -351,24 +350,45 @@ class ImportSession(object):
class ImportTask(object):
"""Represents a single set of items to be imported along with its
intermediate state. May represent an album or a single item.
The import session and stages call the following methods in the
given order.
* `lookup_candidates()` Sets the `common_artist`, `common_album`,
`candidates`, and `rec` attributes. `candidates` is a list of
`AlbumMatch` objects.
* `choose_match()` Uses the session to set the `match` attribute
from the `candidates` list.
* `find_duplicates()` Returns a list of albums from `lib` with the
same artist and album name as the task.
* `apply_metadata()` Sets the attributes of the items from the
task's `match` attribute.
* `add()` Add the imported items and album to the database.
* `manipulate_files()` Copy, move, and write files depending on the
session configuration.
* `finalize()` Update the import progress and cleanup the file
system.
"""
def __init__(self, toppath=None, paths=None, items=None):
self.toppath = toppath
self.paths = paths
self.items = items
self.choice_flag = None
self.cur_album = None
self.cur_artist = None
self.candidates = []
self.rec = None
# TODO remove this eventually
self.should_remove_duplicates = False
self.is_album = True
def set_null_candidates(self):
"""Set the candidates to indicate no album match was found.
"""
self.cur_artist = None
self.cur_album = None
self.candidates = None
self.rec = None
def set_choice(self, choice):
"""Given an AlbumMatch or TrackMatch object or an action constant,
indicates that an action has been selected for this task.
@ -422,12 +442,15 @@ class ImportTask(object):
def imported_items(self):
"""Return a list of Items that should be added to the library.
If this is an album task, return the list of items in the
selected match or everything if the choice is ASIS. If this is a
singleton task, return a list containing the item.
If the tasks applies an album match the method only returns the
matched items.
"""
if self.choice_flag == action.ASIS:
return list(self.items)
# FIXME this should be a simple attribute. There should be no
# need to retrieve the keys of `match.mapping`. This requires
# that we remove unmatched items from the list.
elif self.choice_flag == action.APPLY:
return self.match.mapping.keys()
else:
@ -436,6 +459,8 @@ class ImportTask(object):
def apply_metadata(self):
"""Copy metadata from match info to the items.
"""
# TODO call should be more descriptive like
# apply_metadata(self.match, self.items)
autotag.apply_metadata(self.match.info, self.match.mapping)
def duplicate_items(self, lib):
@ -446,13 +471,13 @@ class ImportTask(object):
def remove_duplicates(self, lib):
duplicate_items = self.duplicate_items(lib)
log.debug('removing %i old duplicated items' %
len(duplicate_items))
log.debug(u'removing {0} old duplicated items'
.format(len(duplicate_items)))
for item in duplicate_items:
item.remove()
if lib.directory in util.ancestry(item.path):
log.debug(u'deleting duplicate %s' %
util.displayable_path(item.path))
log.debug(u'deleting duplicate {0}'
.format(util.displayable_path(item.path)))
util.remove(item.path)
util.prune_dirs(os.path.dirname(item.path),
lib.directory)
@ -542,7 +567,7 @@ class ImportTask(object):
duplicates.append(album)
return duplicates
def infer_album_fields(self):
def align_album_level_fields(self):
"""Make the some album fields equal across `self.items`
"""
changes = {}
@ -617,28 +642,91 @@ class ImportTask(object):
def add(self, lib):
"""Add the items as an album to the library and remove replaced items.
"""
self.align_album_level_fields()
with lib.transaction():
self.record_replaced(lib)
self.remove_replaced(lib)
self.album = lib.add_album(self.imported_items())
self.reimport_metadata(lib)
def remove_replaced(self, lib):
"""Removes all the items from the library that have the same
path as an item from this task.
Records the replaced items in the `replaced_items` dictionary
def record_replaced(self, lib):
"""Records the replaced items and albums in the `replaced_items`
and `replaced_albums` dictionaries.
"""
self.replaced_items = defaultdict(list)
self.replaced_albums = defaultdict(list)
replaced_album_ids = set()
for item in self.imported_items():
dup_items = list(lib.items(
dbcore.query.BytesQuery('path', item.path)
))
self.replaced_items[item] = dup_items
for dup_item in dup_items:
log.debug('replacing item %i: %s' %
(dup_item.id, displayable_path(item.path)))
if (not dup_item.album_id or
dup_item.album_id in replaced_album_ids):
continue
replaced_album = dup_item.get_album()
if replaced_album:
replaced_album_ids.add(dup_item.album_id)
self.replaced_albums[replaced_album.path] = replaced_album
def reimport_metadata(self, lib):
"""For reimports, preserves metadata for reimported items and
albums.
"""
if self.is_album:
replaced_album = self.replaced_albums.get(self.album.path)
if replaced_album:
self.album.added = replaced_album.added
self.album.update(replaced_album._values_flex)
self.album.store()
log.debug(
u'Reimported album: added {0}, flexible '
u'attributes {1} from album {2} for {3}'.format(
self.album.added,
replaced_album._values_flex.keys(),
replaced_album.id,
displayable_path(self.album.path),
)
)
for item in self.imported_items():
dup_items = self.replaced_items[item]
for dup_item in dup_items:
if dup_item.added and dup_item.added != item.added:
item.added = dup_item.added
log.debug(
u'Reimported item added {0} '
u'from item {1} for {2}'.format(
item.added,
dup_item.id,
displayable_path(item.path),
)
)
item.update(dup_item._values_flex)
log.debug(
u'Reimported item flexible attributes {0} '
u'from item {1} for {2}'.format(
dup_item._values_flex.keys(),
dup_item.id,
displayable_path(item.path),
)
)
item.store()
def remove_replaced(self, lib):
"""Removes all the items from the library that have the same
path as an item from this task.
"""
for item in self.imported_items():
for dup_item in self.replaced_items[item]:
log.debug(u'Replacing item {0}: {1}'
.format(dup_item.id,
displayable_path(item.path)))
dup_item.remove()
log.debug('%i of %i items replaced' % (len(self.replaced_items),
len(self.imported_items())))
log.debug(u'{0} of {1} items replaced'
.format(sum(bool(l) for l in self.replaced_items.values()),
len(self.imported_items())))
def choose_match(self, session):
"""Ask the session which match should apply and apply it.
@ -726,8 +814,10 @@ class SingletonImportTask(ImportTask):
def add(self, lib):
with lib.transaction():
self.record_replaced(lib)
self.remove_replaced(lib)
lib.add(self.item)
self.reimport_metadata(lib)
def infer_album_fields(self):
raise NotImplementedError
@ -958,17 +1048,17 @@ def read_tasks(session):
archive_task = None
if ArchiveImportTask.is_archive(syspath(toppath)):
if not (session.config['move'] or session.config['copy']):
log.warn("Archive importing requires either "
log.warn(u"Archive importing requires either "
"'copy' or 'move' to be enabled.")
continue
log.debug('extracting archive {0}'
log.debug(u'extracting archive {0}'
.format(displayable_path(toppath)))
archive_task = ArchiveImportTask(toppath)
try:
archive_task.extract()
except Exception as exc:
log.error('extraction failed: {0}'.format(exc))
log.error(u'extraction failed: {0}'.format(exc))
continue
# Continue reading albums from the extracted directory.
@ -1036,8 +1126,8 @@ def query_tasks(session):
else:
# Search for albums.
for album in session.lib.albums(session.query):
log.debug('yielding album %i: %s - %s' %
(album.id, album.albumartist, album.album))
log.debug(u'yielding album {0}: {1} - {2}'
.format(album.id, album.albumartist, album.album))
items = list(album.items())
# Clear IDs from re-tagged items so they appear "fresh" when
@ -1062,7 +1152,7 @@ def lookup_candidates(session, task):
return
plugins.send('import_task_start', session=session, task=task)
log.debug('Looking up: %s' % displayable_path(task.paths))
log.debug(u'Looking up: {0}'.format(displayable_path(task.paths)))
task.lookup_candidates()
@ -1140,9 +1230,6 @@ def import_asis(session, task):
return
log.info(displayable_path(task.paths))
# Behave as if ASIS were selected.
task.set_null_candidates()
task.set_choice(action.ASIS)
@ -1159,10 +1246,6 @@ def apply_choices(session, task):
task.apply_metadata()
plugins.send('import_task_apply', session=session, task=task)
# Infer album-level fields.
if task.is_album:
task.infer_album_fields()
task.add(session.lib)

View file

@ -60,13 +60,10 @@ class PathQuery(dbcore.FieldQuery):
# Library-specific field types.
class DateType(types.Type):
class DateType(types.Float):
# TODO representation should be `datetime` object
# TODO distinguish beetween date and time types
sql = u'REAL'
query = dbcore.query.DateQuery
null = 0.0
def format(self, value):
return time.strftime(beets.config['time_format'].get(unicode),
@ -89,6 +86,7 @@ class DateType(types.Type):
class PathType(types.Type):
sql = u'BLOB'
query = PathQuery
model_type = bytes
def format(self, value):
return util.displayable_path(value)
@ -109,6 +107,14 @@ class PathType(types.Type):
else:
return value
def from_sql(self, sql_value):
return self.normalize(sql_value)
def to_sql(self, value):
if isinstance(value, str):
value = buffer(value)
return value
class MusicalKey(types.String):
"""String representing the musical key of a song.
@ -137,6 +143,34 @@ class MusicalKey(types.String):
return self.parse(key)
# Library-specific sort types.
class SmartArtistSort(dbcore.query.Sort):
"""Sort by artist (either album artist or track artist),
prioritizing the sort field over the raw field.
"""
def __init__(self, model_cls, ascending=True):
self.album = model_cls is Album
self.ascending = ascending
def order_clause(self):
order = "ASC" if self.ascending else "DESC"
if self.album:
field = 'albumartist'
else:
field = 'artist'
return ('(CASE {0}_sort WHEN NULL THEN {0} '
'WHEN "" THEN {0} '
'ELSE {0}_sort END) {1}').format(field, order)
def sort(self, objs):
if self.album:
key = lambda a: a.albumartist_sort or a.albumartist
else:
key = lambda i: i.artist_sort or i.artist
return sorted(objs, key=key, reverse=not self.ascending)
# Special path format key.
PF_KEY_DEFAULT = 'default'
@ -188,7 +222,6 @@ class WriteError(FileOperationError):
class LibModel(dbcore.Model):
"""Shared concrete functionality for Items and Albums.
"""
_bytes_keys = ('path', 'artpath')
def _template_funcs(self):
funcs = DefaultTemplateFunctions(self, self._db).functions()
@ -341,6 +374,8 @@ class Item(LibModel):
_formatter = FormattedItemMapping
_sorts = {'artist': SmartArtistSort}
@classmethod
def _getters(cls):
getters = plugins.item_field_getters()
@ -438,7 +473,8 @@ class Item(LibModel):
else:
path = normpath(path)
plugins.send('write', item=self, path=path)
tags = dict(self)
plugins.send('write', item=self, path=path, tags=tags)
try:
mediafile = MediaFile(syspath(path),
@ -446,7 +482,7 @@ class Item(LibModel):
except (OSError, IOError, UnreadableFileError) as exc:
raise ReadError(self.path, exc)
mediafile.update(self)
mediafile.update(tags)
try:
mediafile.save()
except (OSError, IOError, MutagenError) as exc:
@ -470,6 +506,22 @@ class Item(LibModel):
log.error(exc)
return False
def try_sync(self, write=None):
"""Synchronize the item with the database and the media file
tags, updating them with this object's current state.
By default, the current `path` for the item is used to write
tags. If `write` is `False`, no tags are written. If `write` is
a path, tags are written to that file instead.
Similar to calling :meth:`write` and :meth:`store`.
"""
if write is True:
write = None
if write is not False:
self.try_write(path=write)
self.store()
# Files themselves.
def move_file(self, dest, copy=False, link=False):
@ -591,7 +643,7 @@ class Item(LibModel):
for query, path_format in path_formats:
if query == PF_KEY_DEFAULT:
continue
(query, _) = get_query_sort(query, type(self))
query, _ = parse_query_string(query, type(self))
if query.match(self):
# The query matches the item! Use the corresponding path
# format.
@ -692,6 +744,11 @@ class Album(LibModel):
_search_fields = ('album', 'albumartist', 'genre')
_sorts = {
'albumartist': SmartArtistSort,
'artist': SmartArtistSort,
}
item_keys = [
'added',
'albumartist',
@ -774,7 +831,9 @@ class Album(LibModel):
return
new_art = util.unique_path(new_art)
log.debug('moving album art %s to %s' % (old_art, new_art))
log.debug(u'moving album art {0} to {1}'
.format(util.displayable_path(old_art),
util.displayable_path(new_art)))
if copy:
util.copy(old_art, new_art)
elif link:
@ -888,71 +947,68 @@ class Album(LibModel):
item[key] = value
item.store()
def try_sync(self, write=True):
"""Synchronize the album and its items with the database and
their files by updating them with this object's current state.
# Query construction and parsing helpers.
`write` indicates whether to write tags to the item files.
"""
self.store()
for item in self.items():
item.try_sync(bool(write))
def get_query_sort(val, model_cls):
"""Take a value which may be None, a query string, a query string
list, or a Query object, and return a suitable Query object and Sort
object.
`model_cls` is the subclass of Model indicating which entity this
is a query for (i.e., Album or Item) and is used to determine which
fields are searched.
# Query construction helpers.
def parse_query_parts(parts, model_cls):
"""Given a beets query string as a list of components, return the
`Query` and `Sort` they represent.
Like `dbcore.parse_sorted_query`, with beets query prefixes and
special path query detection.
"""
# Get query types and their prefix characters.
prefixes = {':': dbcore.query.RegexpQuery}
prefixes.update(plugins.queries())
# Convert a single string into a list of space-separated
# criteria.
if isinstance(val, basestring):
# A bug in Python < 2.7.3 prevents correct shlex splitting of
# Unicode strings.
# http://bugs.python.org/issue6988
if isinstance(val, unicode):
val = val.encode('utf8')
val = [s.decode('utf8') for s in shlex.split(val)]
if val is None:
return (dbcore.query.TrueQuery(), None)
elif isinstance(val, list) or isinstance(val, tuple):
# Special-case path-like queries, which are non-field queries
# containing path separators (/).
if 'path' in model_cls._fields:
path_parts = []
non_path_parts = []
for s in val:
if s.find(os.sep, 0, s.find(':')) != -1:
# Separator precedes colon.
path_parts.append(s)
else:
non_path_parts.append(s)
else:
path_parts = ()
non_path_parts = val
# separate query token and sort token
query_val = [s for s in non_path_parts if not s.endswith(('+', '-'))]
sort_val = [s for s in non_path_parts if s.endswith(('+', '-'))]
# Parse remaining parts and construct an AndQuery.
query = dbcore.query_from_strings(
dbcore.AndQuery, model_cls, prefixes, query_val
)
sort = dbcore.sort_from_strings(model_cls, sort_val)
# Add path queries to aggregate query.
if path_parts:
query.subqueries += [PathQuery('path', s) for s in path_parts]
return query, sort
elif isinstance(val, dbcore.Query):
return val, None
# Special-case path-like queries, which are non-field queries
# containing path separators (/).
if 'path' in model_cls._fields:
path_parts = []
non_path_parts = []
for s in parts:
if s.find(os.sep, 0, s.find(':')) != -1:
# Separator precedes colon.
path_parts.append(s)
else:
non_path_parts.append(s)
else:
raise ValueError('query must be None or have type Query or str')
path_parts = ()
non_path_parts = parts
query, sort = dbcore.parse_sorted_query(
model_cls, non_path_parts, prefixes
)
# Add path queries to aggregate query.
if path_parts:
query.subqueries += [PathQuery('path', s) for s in path_parts]
return query, sort
def parse_query_string(s, model_cls):
"""Given a beets query string, return the `Query` and `Sort` they
represent.
The string is split into components using shell-like syntax.
"""
# A bug in Python < 2.7.3 prevents correct shlex splitting of
# Unicode strings.
# http://bugs.python.org/issue6988
if isinstance(s, unicode):
s = s.encode('utf8')
parts = [p.decode('utf8') for p in shlex.split(s)]
return parse_query_parts(parts, model_cls)
# The Library: interface to the database.
@ -1016,30 +1072,41 @@ class Library(dbcore.Database):
# Querying.
def _fetch(self, model_cls, query, sort_order=None):
"""Parse a query and fetch. If a order specification is present in the
query string the sort_order argument is ignored.
"""
query, sort = get_query_sort(query, model_cls)
sort = sort or sort_order
def _fetch(self, model_cls, query, sort=None):
"""Parse a query and fetch. If a order specification is present
in the query string the `sort` argument is ignored.
"""
# Parse the query, if necessary.
parsed_sort = None
if isinstance(query, basestring):
query, parsed_sort = parse_query_string(query, model_cls)
elif isinstance(query, (list, tuple)):
query, parsed_sort = parse_query_parts(query, model_cls)
# Any non-null sort specified by the parsed query overrides the
# provided sort.
if parsed_sort and not isinstance(parsed_sort, dbcore.query.NullSort):
sort = parsed_sort
return super(Library, self)._fetch(
model_cls, query, sort
)
def albums(self, query=None, sort_order=None):
"""Get a sorted list of :class:`Album` objects matching the
given sort order. If a order specification is present in the query
string the sort_order argument is ignored.
def albums(self, query=None, sort=None):
"""Get :class:`Album` objects matching the query.
"""
return self._fetch(Album, query, sort_order)
sort = sort or dbcore.sort_from_strings(
Album, beets.config['sort_album'].as_str_seq()
)
return self._fetch(Album, query, sort)
def items(self, query=None, sort_order=None):
"""Get a sorted list of :class:`Item` objects matching the given
given sort order. If a order specification is present in the query
string the sort_order argument is ignored.
def items(self, query=None, sort=None):
"""Get :class:`Item` objects matching the query.
"""
return self._fetch(Item, query, sort_order)
sort = sort or dbcore.sort_from_strings(
Item, beets.config['sort_item'].as_str_seq()
)
return self._fetch(Item, query, sort)
# Convenience accessors.

View file

@ -1263,7 +1263,7 @@ class MediaFile(object):
except Exception as exc:
# Isolate bugs in Mutagen.
log.debug(traceback.format_exc())
log.error('uncaught Mutagen exception in open: {0}'.format(exc))
log.error(u'uncaught Mutagen exception in open: {0}'.format(exc))
raise MutagenError(path, exc)
if self.mgfile is None:
@ -1330,7 +1330,7 @@ class MediaFile(object):
raise
except Exception as exc:
log.debug(traceback.format_exc())
log.error('uncaught Mutagen exception in save: {0}'.format(exc))
log.error(u'uncaught Mutagen exception in save: {0}'.format(exc))
raise MutagenError(self.path, exc)
def delete(self):

View file

@ -202,7 +202,7 @@ def load_plugins(names=()):
except ImportError as exc:
# Again, this is hacky:
if exc.args[0].endswith(' ' + name):
log.warn('** plugin %s not found' % name)
log.warn(u'** plugin {0} not found'.format(name))
else:
raise
else:
@ -212,7 +212,7 @@ def load_plugins(names=()):
_classes.add(obj)
except:
log.warn('** error loading plugin %s' % name)
log.warn(u'** error loading plugin {0}'.format(name))
log.warn(traceback.format_exc())
@ -395,7 +395,7 @@ def send(event, **arguments):
Returns a list of return values from the handlers.
"""
log.debug('Sending event: %s' % event)
log.debug(u'Sending event: {0}'.format(event))
for handler in event_handlers()[event]:
# Don't break legacy plugins if we want to pass more arguments
argspec = inspect.getargspec(handler).args

View file

@ -441,30 +441,6 @@ def colordiff(a, b, highlight='red'):
return unicode(a), unicode(b)
def color_diff_suffix(a, b, highlight='red'):
"""Colorize the differing suffix between two strings."""
a, b = unicode(a), unicode(b)
if not config['color']:
return a, b
# Fast path.
if a == b:
return a, b
# Find the longest common prefix.
first_diff = None
for i in range(min(len(a), len(b))):
if a[i] != b[i]:
first_diff = i
break
else:
first_diff = min(len(a), len(b))
# Colorize from the first difference on.
return (a[:first_diff] + colorize(highlight, a[first_diff:]),
b[:first_diff] + colorize(highlight, b[first_diff:]))
def get_path_formats(subview=None):
"""Get the configuration's path formats as a list of query/template
pairs.
@ -895,10 +871,10 @@ def _configure(options):
config_path = config.user_config_path()
if os.path.isfile(config_path):
log.debug('user configuration: {0}'.format(
log.debug(u'user configuration: {0}'.format(
util.displayable_path(config_path)))
else:
log.debug('no user configuration found at {0}'.format(
log.debug(u'no user configuration found at {0}'.format(
util.displayable_path(config_path)))
log.debug(u'data directory: {0}'
@ -923,10 +899,8 @@ def _open_library(config):
))
log.debug(u'library database: {0}\n'
u'library directory: {1}'
.format(
util.displayable_path(lib.path),
util.displayable_path(lib.directory),
))
.format(util.displayable_path(lib.path),
util.displayable_path(lib.directory)))
return lib

View file

@ -20,7 +20,6 @@ from __future__ import print_function
import logging
import os
import time
import itertools
import codecs
import platform
import re
@ -39,7 +38,6 @@ from beets.util.functemplate import Template
from beets import library
from beets import config
from beets.util.confit import _package_path
from beets.dbcore import sort_from_strings
VARIOUS_ARTISTS = u'Various Artists'
@ -320,17 +318,9 @@ def show_change(cur_artist, cur_album, match):
color = 'lightgray'
else:
color = 'red'
if (cur_track + new_track).count('-') == 1:
lhs_track, rhs_track = (ui.colorize(color, cur_track),
ui.colorize(color, new_track))
else:
color = 'red'
lhs_track, rhs_track = ui.color_diff_suffix(cur_track,
new_track)
templ = (ui.colorize(color, u' (#') + u'{0}' +
ui.colorize(color, u')'))
lhs += templ.format(lhs_track)
rhs += templ.format(rhs_track)
templ = ui.colorize(color, u' (#{0})')
lhs += templ.format(cur_track)
rhs += templ.format(new_track)
lhs_width += len(cur_track) + 4
# Length change.
@ -339,12 +329,9 @@ def show_change(cur_artist, cur_album, match):
config['ui']['length_diff_thresh'].as_number():
cur_length = ui.human_seconds_short(item.length)
new_length = ui.human_seconds_short(track_info.length)
lhs_length, rhs_length = ui.color_diff_suffix(cur_length,
new_length)
templ = (ui.colorize('red', u' (') + u'{0}' +
ui.colorize('red', u')'))
lhs += templ.format(lhs_length)
rhs += templ.format(rhs_length)
templ = ui.colorize('red', u' ({0})')
lhs += templ.format(cur_length)
rhs += templ.format(new_length)
lhs_width += len(cur_length) + 3
# Penalties.
@ -777,12 +764,12 @@ class TerminalImportSession(importer.ImportSession):
"""Decide what to do when a new album or item seems similar to one
that's already in the library.
"""
log.warn("This %s is already in the library!" %
("album" if task.is_album else "item"))
log.warn(u"This {0} is already in the library!"
.format("album" if task.is_album else "item"))
if config['import']['quiet']:
# In quiet mode, don't prompt -- just skip.
log.info('Skipping.')
log.info(u'Skipping.')
sel = 's'
else:
# Print some detail about the existing and new items so the
@ -967,18 +954,11 @@ def list_items(lib, query, album, fmt):
albums instead of single items.
"""
tmpl = Template(ui._pick_format(album, fmt))
if album:
sort_parts = str(config['sort_album']).split()
sort_order = sort_from_strings(library.Album,
sort_parts)
for album in lib.albums(query, sort_order):
for album in lib.albums(query):
ui.print_obj(album, lib, tmpl)
else:
sort_parts = str(config['sort_item']).split()
sort_order = sort_from_strings(library.Item,
sort_parts)
for item in lib.items(query, sort_order):
for item in lib.items(query):
ui.print_obj(item, lib, tmpl)
@ -1030,8 +1010,8 @@ def update_items(lib, query, album, move, pretend):
# Did the item change since last checked?
if item.current_mtime() <= item.mtime:
log.debug(u'skipping %s because mtime is up to date (%i)' %
(displayable_path(item.path), item.mtime))
log.debug(u'skipping {0} because mtime is up to date ({1})'
.format(displayable_path(item.path), item.mtime))
continue
# Read new data.
@ -1081,7 +1061,7 @@ def update_items(lib, query, album, move, pretend):
continue
album = lib.get_album(album_id)
if not album: # Empty albums have already been removed.
log.debug('emptied album %i' % album_id)
log.debug(u'emptied album {0}'.format(album_id))
continue
first_item = album.items().get()
@ -1092,7 +1072,7 @@ def update_items(lib, query, album, move, pretend):
# Move album art (and any inconsistent items).
if move and lib.directory in ancestry(first_item.path):
log.debug('moving album %i' % album_id)
log.debug(u'moving album {0}'.format(album_id))
album.move()
@ -1298,25 +1278,17 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm):
if not ui.input_yn('Really modify%s (Y/n)?' % extra):
return
# Apply changes to database.
# Apply changes to database and files
with lib.transaction():
for obj in changed:
if move:
cur_path = obj.path
if lib.directory in ancestry(cur_path): # In library?
log.debug('moving object %s' % cur_path)
log.debug(u'moving object {0}'
.format(displayable_path(cur_path)))
obj.move()
obj.store()
# Apply tags if requested.
if write:
if album:
changed_items = itertools.chain(*(a.items() for a in changed))
else:
changed_items = changed
for item in changed_items:
item.try_write()
obj.try_sync(write)
def modify_parse_args(args):
@ -1391,9 +1363,9 @@ def move_items(lib, dest, query, copy, album):
action = 'Copying' if copy else 'Moving'
entity = 'album' if album else 'item'
log.info('%s %i %ss.' % (action, len(objs), entity))
log.info(u'{0} {1} {2}s.'.format(action, len(objs), entity))
for obj in objs:
log.debug('moving: %s' % obj.path)
log.debug(u'moving: {0}'.format(util.displayable_path(obj.path)))
obj.move(copy, basedir=dest)
obj.store()
@ -1457,7 +1429,7 @@ def write_items(lib, query, pretend, force):
changed = ui.show_model_changes(item, clean_item,
library.Item._media_fields, force)
if (changed or force) and not pretend:
item.try_write()
item.try_sync()
def write_func(lib, opts, args):

View file

@ -1,5 +1,5 @@
# This file is part of beets.
# Copyright 2013, Fabrice Laporte
# Copyright 2014, Fabrice Laporte
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@ -18,6 +18,7 @@ public resizing proxy if neither is available.
import urllib
import subprocess
import os
import re
from tempfile import NamedTemporaryFile
import logging
from beets import util
@ -76,7 +77,7 @@ def pil_resize(maxwidth, path_in, path_out=None):
def im_resize(maxwidth, path_in, path_out=None):
"""Resize using ImageMagick's ``convert`` tool.
tool. Return the output path of resized image.
Return the output path of resized image.
"""
path_out = path_out or temp_file_for(path_in)
log.debug(u'artresizer: ImageMagick resizing {0} to {1}'.format(
@ -132,8 +133,9 @@ class ArtResizer(object):
"""Create a resizer object for the given method or, if none is
specified, with an inferred method.
"""
self.method = method or self._guess_method()
self.method = self._check_method(method)
log.debug(u"artresizer: method is {0}".format(self.method))
self.can_compare = self._can_compare()
def resize(self, maxwidth, path_in, path_out=None):
"""Manipulate an image file according to the method, returning a
@ -159,30 +161,51 @@ class ArtResizer(object):
@property
def local(self):
"""A boolean indicating whether the resizing method is performed
locally (i.e., PIL or IMAGEMAGICK).
locally (i.e., PIL or ImageMagick).
"""
return self.method in BACKEND_FUNCS
return self.method[0] in BACKEND_FUNCS
def _can_compare(self):
"""A boolean indicating whether image comparison is available"""
return self.method[0] == IMAGEMAGICK and self.method[1] > (6, 8, 7)
@staticmethod
def _guess_method():
"""Determine which resizing method to use. Returns PIL,
IMAGEMAGICK, or WEBPROXY depending on available dependencies.
def _check_method(method=None):
"""A tuple indicating whether current method is available and its
version. If no method is given, it returns a supported one.
"""
# Try importing PIL.
try:
__import__('PIL', fromlist=['Image'])
return PIL
except ImportError:
pass
# Guess available method
if not method:
for m in [IMAGEMAGICK, PIL]:
_, version = ArtResizer._check_method(m)
if version:
return (m, version)
return (WEBPROXY, (0))
# Try invoking ImageMagick's "convert".
try:
out = util.command_output(['convert', '--version'])
if 'imagemagick' in out.lower():
# system32/convert.exe may be interfering
return IMAGEMAGICK
except (subprocess.CalledProcessError, OSError):
pass
if method == IMAGEMAGICK:
# Fall back to Web proxy method.
return WEBPROXY
# Try invoking ImageMagick's "convert".
try:
out = util.command_output(['identify', '--version'])
if 'imagemagick' in out.lower():
pattern = r".+ (\d+)\.(\d+)\.(\d+).*"
match = re.search(pattern, out)
if match:
return (IMAGEMAGICK,
(int(match.group(1)),
int(match.group(2)),
int(match.group(3))))
return (IMAGEMAGICK, (0))
except (subprocess.CalledProcessError, OSError):
return (IMAGEMAGICK, None)
if method == PIL:
# Try importing PIL.
try:
__import__('PIL', fromlist=['Image'])
return (PIL, (0))
except ImportError:
return (PIL, None)

View file

@ -194,7 +194,7 @@ class BeatportPlugin(BeetsPlugin):
try:
return self._get_releases(query)
except BeatportAPIError as e:
log.debug('Beatport API Error: %s (query: %s)' % (e, query))
log.debug(u'Beatport API Error: {0} (query: {1})'.format(e, query))
return []
def item_candidates(self, item, artist, title):
@ -205,14 +205,14 @@ class BeatportPlugin(BeetsPlugin):
try:
return self._get_tracks(query)
except BeatportAPIError as e:
log.debug('Beatport API Error: %s (query: %s)' % (e, query))
log.debug(u'Beatport API Error: {0} (query: {1})'.format(e, query))
return []
def album_for_id(self, release_id):
"""Fetches a release by its Beatport ID and returns an AlbumInfo object
or None if the release is not found.
"""
log.debug('Searching Beatport for release %s' % str(release_id))
log.debug(u'Searching Beatport for release {0}'.format(release_id))
match = re.search(r'(^|beatport\.com/release/.+/)(\d+)$', release_id)
if not match:
return None
@ -224,7 +224,7 @@ class BeatportPlugin(BeetsPlugin):
"""Fetches a track by its Beatport ID and returns a TrackInfo object
or None if the track is not found.
"""
log.debug('Searching Beatport for track %s' % str(track_id))
log.debug(u'Searching Beatport for track {0}'.format(str(track_id)))
match = re.search(r'(^|beatport\.com/track/.+/)(\d+)$', track_id)
if not match:
return None

View file

@ -1149,20 +1149,23 @@ class BPDPlugin(BeetsPlugin):
'host': u'',
'port': 6600,
'password': u'',
'volume': VOLUME_MAX,
})
def start_bpd(self, lib, host, port, password, debug):
def start_bpd(self, lib, host, port, password, volume, debug):
"""Starts a BPD server."""
if debug:
log.setLevel(logging.DEBUG)
else:
log.setLevel(logging.WARNING)
try:
Server(lib, host, port, password).run()
server = Server(lib, host, port, password)
server.cmd_setvol(None, volume)
server.run()
except NoGstreamerError:
global_log.error('Gstreamer Python bindings not found.')
global_log.error('Install "python-gst0.10", "py27-gst-python", '
'or similar package to use BPD.')
global_log.error(u'Gstreamer Python bindings not found.')
global_log.error(u'Install "python-gst0.10", "py27-gst-python", '
u'or similar package to use BPD.')
def commands(self):
cmd = beets.ui.Subcommand(
@ -1179,8 +1182,9 @@ class BPDPlugin(BeetsPlugin):
if args:
raise beets.ui.UserError('too many arguments')
password = self.config['password'].get(unicode)
volume = self.config['volume'].get(int)
debug = opts.debug or False
self.start_bpd(lib, host, int(port), password, debug)
self.start_bpd(lib, host, int(port), password, volume, debug)
cmd.func = func
return [cmd]

View file

@ -73,15 +73,15 @@ class BPMPlugin(BeetsPlugin):
item = items[0]
if item['bpm']:
log.info('Found bpm {0}'.format(item['bpm']))
log.info(u'Found bpm {0}'.format(item['bpm']))
if not overwrite:
return
log.info('Press Enter {0} times to the rhythm or Ctrl-D \
to exit'.format(self.config['max_strokes'].get(int)))
log.info(u'Press Enter {0} times to the rhythm or Ctrl-D '
u'to exit'.format(self.config['max_strokes'].get(int)))
new_bpm = bpm(self.config['max_strokes'].get(int))
item['bpm'] = int(new_bpm)
if write:
item.try_write()
item.store()
log.info('Added new bpm {0}'.format(item['bpm']))
log.info(u'Added new bpm {0}'.format(item['bpm']))

View file

@ -53,32 +53,33 @@ def acoustid_match(path):
try:
duration, fp = acoustid.fingerprint_file(util.syspath(path))
except acoustid.FingerprintGenerationError as exc:
log.error('fingerprinting of %s failed: %s' %
(repr(path), str(exc)))
log.error(u'fingerprinting of {0} failed: {1}'
.format(util.displayable_path(repr(path)), str(exc)))
return None
_fingerprints[path] = fp
try:
res = acoustid.lookup(API_KEY, fp, duration,
meta='recordings releases')
except acoustid.AcoustidError as exc:
log.debug('fingerprint matching %s failed: %s' %
(repr(path), str(exc)))
log.debug(u'fingerprint matching {0} failed: {1}'
.format(util.displayable_path(repr(path)), str(exc)))
return None
log.debug('chroma: fingerprinted %s' % repr(path))
log.debug(u'chroma: fingerprinted {0}'
.format(util.displayable_path(repr(path))))
# Ensure the response is usable and parse it.
if res['status'] != 'ok' or not res.get('results'):
log.debug('chroma: no match found')
log.debug(u'chroma: no match found')
return None
result = res['results'][0] # Best match.
if result['score'] < SCORE_THRESH:
log.debug('chroma: no results above threshold')
log.debug(u'chroma: no results above threshold')
return None
_acoustids[path] = result['id']
# Get recording and releases from the result.
if not result.get('recordings'):
log.debug('chroma: no recordings found')
log.debug(u'chroma: no recordings found')
return None
recording_ids = []
release_ids = []
@ -87,7 +88,7 @@ def acoustid_match(path):
if 'releases' in recording:
release_ids += [rel['id'] for rel in recording['releases']]
log.debug('chroma: matched recordings {0}'.format(recording_ids))
log.debug(u'chroma: matched recordings {0}'.format(recording_ids))
_matches[path] = recording_ids, release_ids
@ -141,7 +142,7 @@ class AcoustidPlugin(plugins.BeetsPlugin):
if album:
albums.append(album)
log.debug('acoustid album candidates: %i' % len(albums))
log.debug(u'acoustid album candidates: {0}'.format(len(albums)))
return albums
def item_candidates(self, item, artist, title):
@ -154,7 +155,7 @@ class AcoustidPlugin(plugins.BeetsPlugin):
track = hooks.track_for_mbid(recording_id)
if track:
tracks.append(track)
log.debug('acoustid item candidates: {0}'.format(len(tracks)))
log.debug(u'acoustid item candidates: {0}'.format(len(tracks)))
return tracks
def commands(self):
@ -216,7 +217,7 @@ def submit_items(userkey, items, chunksize=64):
def submit_chunk():
"""Submit the current accumulated fingerprint data."""
log.info('submitting {0} fingerprints'.format(len(data)))
log.info(u'submitting {0} fingerprints'.format(len(data)))
try:
acoustid.submit(API_KEY, userkey, data)
except acoustid.AcoustidError as exc:
@ -233,7 +234,7 @@ def submit_items(userkey, items, chunksize=64):
}
if item.mb_trackid:
item_data['mbid'] = item.mb_trackid
log.debug('submitting MBID')
log.debug(u'submitting MBID')
else:
item_data.update({
'track': item.title,
@ -244,7 +245,7 @@ def submit_items(userkey, items, chunksize=64):
'trackno': item.track,
'discno': item.disc,
})
log.debug('submitting textual metadata')
log.debug(u'submitting textual metadata')
data.append(item_data)
# If we have enough data, submit a chunk.
@ -294,6 +295,5 @@ def fingerprint_item(item, write=False):
item.store()
return item.acoustid_fingerprint
except acoustid.FingerprintGenerationError as exc:
log.info(
'fingerprint generation failed: {0}'.format(exc)
)
log.info(u'fingerprint generation failed: {0}'
.format(exc))

View file

@ -151,8 +151,12 @@ def convert_item(dest_dir, keep_new, path_formats, format, pretend=False):
if keep_new:
original = dest
converted = item.path
if should_transcode(item, format):
converted = replace_ext(converted, ext)
else:
original = item.path
if should_transcode(item, format):
dest = replace_ext(dest, ext)
converted = dest
# Ensure that only one thread tries to create directories at a
@ -181,7 +185,6 @@ def convert_item(dest_dir, keep_new, path_formats, format, pretend=False):
util.move(item.path, original)
if should_transcode(item, format):
converted = replace_ext(converted, ext)
try:
encode(command, original, converted, pretend)
except subprocess.CalledProcessError:
@ -232,7 +235,7 @@ def convert_on_import(lib, item):
format = config['convert']['format'].get(unicode).lower()
if should_transcode(item, format):
command, ext = get_format()
fd, dest = tempfile.mkstemp(ext)
fd, dest = tempfile.mkstemp('.' + ext)
os.close(fd)
_temp_files.append(dest) # Delete the transcode later.
try:
@ -338,7 +341,7 @@ class ConvertPlugin(BeetsPlugin):
help='set the destination directory')
cmd.parser.add_option('-f', '--format', action='store', dest='format',
help='set the destination directory')
cmd.parser.add_option('-y', '--yes', action='store', dest='yes',
cmd.parser.add_option('-y', '--yes', action='store_true', dest='yes',
help='do not ask for confirmation')
cmd.func = convert_func
return [cmd]

View file

@ -60,14 +60,14 @@ class DiscogsPlugin(BeetsPlugin):
try:
return self.get_albums(query)
except DiscogsAPIError as e:
log.debug('Discogs API Error: %s (query: %s' % (e, query))
log.debug(u'Discogs API Error: {0} (query: {1})'.format(e, query))
return []
def album_for_id(self, album_id):
"""Fetches an album by its Discogs ID and returns an AlbumInfo object
or None if the album is not found.
"""
log.debug('Searching discogs for release %s' % str(album_id))
log.debug(u'Searching Discogs for release {0}'.format(str(album_id)))
# Discogs-IDs are simple integers. We only look for those at the end
# of an input string as to avoid confusion with other metadata plugins.
# An optional bracket can follow the integer, as this is how discogs
@ -82,8 +82,8 @@ class DiscogsPlugin(BeetsPlugin):
getattr(result, 'title')
except DiscogsAPIError as e:
if e.message != '404 Not Found':
log.debug('Discogs API Error: %s (query: %s)'
% (e, result._uri))
log.debug(u'Discogs API Error: {0} (query: {1})'
.format(e, result._uri))
return None
return self.get_album_info(result)
@ -225,7 +225,7 @@ class DiscogsPlugin(BeetsPlugin):
if match:
medium, index = match.groups()
else:
log.debug('Invalid discogs position: %s' % position)
log.debug(u'Invalid Discogs position: {0}'.format(position))
medium = index = None
return medium or None, index or None

View file

@ -56,20 +56,20 @@ def _checksum(item, prog):
key = args[0]
checksum = getattr(item, key, False)
if not checksum:
log.debug('%s: key %s on item %s not cached: computing checksum',
PLUGIN, key, displayable_path(item.path))
log.debug(u'{0}: key {1} on item {2} not cached: computing checksum'
.format(PLUGIN, key, displayable_path(item.path)))
try:
checksum = command_output(args)
setattr(item, key, checksum)
item.store()
log.debug('%s: computed checksum for %s using %s',
PLUGIN, item.title, key)
log.debug(u'{)}: computed checksum for {1} using {2}'
.format(PLUGIN, item.title, key))
except subprocess.CalledProcessError as e:
log.debug('%s: failed to checksum %s: %s',
PLUGIN, displayable_path(item.path), e)
log.debug(u'{0}: failed to checksum {1}: {2}'
.format(PLUGIN, displayable_path(item.path), e))
else:
log.debug('%s: key %s on item %s cached: not computing checksum',
PLUGIN, key, displayable_path(item.path))
log.debug(u'{0}: key {1} on item {2} cached: not computing checksum'
.format(PLUGIN, key, displayable_path(item.path)))
return key, checksum
@ -86,8 +86,8 @@ def _group_by(objs, keys):
key = '\001'.join(values)
counts[key].append(obj)
else:
log.debug('%s: all keys %s on item %s are null: skipping',
PLUGIN, str(keys), displayable_path(obj.path))
log.debug(u'{0}: all keys {1} on item {2} are null: skipping'
.format(PLUGIN, str(keys), displayable_path(obj.path)))
return counts

View file

@ -40,19 +40,19 @@ def fetch_item_tempo(lib, loglevel, item, write):
"""
# Skip if the item already has the tempo field.
if item.bpm:
log.log(loglevel, u'bpm already present: %s - %s' %
(item.artist, item.title))
log.log(loglevel, u'bpm already present: {0} - {1}'
.format(item.artist, item.title))
return
# Fetch tempo.
tempo = get_tempo(item.artist, item.title, item.length)
if not tempo:
log.log(loglevel, u'tempo not found: %s - %s' %
(item.artist, item.title))
log.log(loglevel, u'tempo not found: {0} - {1}'
.format(item.artist, item.title))
return
log.log(loglevel, u'fetched tempo: %s - %s' %
(item.artist, item.title))
log.log(loglevel, u'fetched tempo: {0} - {1}'
.format(item.artist, item.title))
item.bpm = int(tempo)
if write:
item.try_write()

View file

@ -16,6 +16,9 @@
import os.path
import logging
import imghdr
import subprocess
import platform
from tempfile import NamedTemporaryFile
from beets.plugins import BeetsPlugin
from beets import mediafile
@ -25,6 +28,7 @@ from beets.util import syspath, normpath, displayable_path
from beets.util.artresizer import ArtResizer
from beets import config
log = logging.getLogger('beets')
@ -36,12 +40,18 @@ class EmbedCoverArtPlugin(BeetsPlugin):
self.config.add({
'maxwidth': 0,
'auto': True,
'compare_threshold': 0,
})
if self.config['maxwidth'].get(int) and \
not ArtResizer.shared.local:
if self.config['maxwidth'].get(int) and not ArtResizer.shared.local:
self.config['maxwidth'] = 0
log.warn("embedart: ImageMagick or PIL not found; "
"'maxwidth' option ignored")
log.warn(u"embedart: ImageMagick or PIL not found; "
u"'maxwidth' option ignored")
if self.config['compare_threshold'].get(int) and not \
ArtResizer.shared.can_compare:
self.config['compare_threshold'] = 0
log.warn(u"embedart: ImageMagick 6.8.7 or higher not installed; "
u"'compare_threshold' option ignored")
def commands(self):
# Embed command.
@ -52,12 +62,14 @@ class EmbedCoverArtPlugin(BeetsPlugin):
'-f', '--file', metavar='PATH', help='the image file to embed'
)
maxwidth = config['embedart']['maxwidth'].get(int)
compare_threshold = config['embedart']['compare_threshold'].get(int)
def embed_func(lib, opts, args):
if opts.file:
imagepath = normpath(opts.file)
for item in lib.items(decargs(args)):
embed_item(item, imagepath, maxwidth)
embed_item(item, imagepath, maxwidth, None,
compare_threshold)
else:
for album in lib.albums(decargs(args)):
embed_album(album, maxwidth)
@ -72,7 +84,8 @@ class EmbedCoverArtPlugin(BeetsPlugin):
def extract_func(lib, opts, args):
outpath = normpath(opts.outpath or 'cover')
extract(lib, outpath, decargs(args))
item = lib.items(decargs(args)).get()
extract(outpath, item)
extract_cmd.func = extract_func
# Clear command.
@ -94,16 +107,22 @@ def album_imported(lib, album):
embed_album(album, config['embedart']['maxwidth'].get(int))
def embed_item(item, imagepath, maxwidth=None, itempath=None):
def embed_item(item, imagepath, maxwidth=None, itempath=None,
compare_threshold=0):
"""Embed an image into the item's media file.
"""
if compare_threshold:
if not check_art_similarity(item, imagepath, compare_threshold):
log.warn('Image not similar, skipping it.')
return
try:
log.info(u'embedart: writing %s', displayable_path(imagepath))
item['images'] = [_mediafile_image(imagepath, maxwidth)]
item.try_write(itempath)
except IOError as exc:
log.error(u'embedart: could not read image file: {0}'.format(exc))
finally:
else:
# We don't want to store the image in the database
item.try_write(itempath)
del item['images']
@ -124,7 +143,43 @@ def embed_album(album, maxwidth=None):
.format(album))
for item in album.items():
embed_item(item, imagepath, maxwidth)
embed_item(item, imagepath, maxwidth, None,
config['embedart']['compare_threshold'].get(int))
def check_art_similarity(item, imagepath, compare_threshold):
"""A boolean indicating if an image is similar to embedded item art.
"""
with NamedTemporaryFile(delete=True) as f:
art = extract(f.name, item)
if art:
# Converting images to grayscale tends to minimize the weight
# of colors in the diff score
cmd = 'convert {0} {1} -colorspace gray MIFF:- | ' \
'compare -metric PHASH - null:'.format(syspath(imagepath),
syspath(art))
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=platform.system() != 'Windows',
shell=True)
stdout, stderr = proc.communicate()
if proc.returncode:
if proc.returncode != 1:
log.warn(u'embedart: IM phashes compare failed for {0}, \
{1}'.format(displayable_path(imagepath),
displayable_path(art)))
return
phashDiff = float(stderr)
else:
phashDiff = float(stdout)
log.info(u'embedart: compare PHASH score is {0}'.format(phashDiff))
if phashDiff > compare_threshold:
return False
return True
def _mediafile_image(image_path, maxwidth=None):
@ -142,10 +197,9 @@ def _mediafile_image(image_path, maxwidth=None):
# 'extractart' command.
def extract(lib, outpath, query):
item = lib.items(query).get()
def extract(outpath, item):
if not item:
log.error('No item matches query.')
log.error(u'No item matches query.')
return
# Extract the art.
@ -159,29 +213,30 @@ def extract(lib, outpath, query):
art = mf.art
if not art:
log.error('No album art present in %s - %s.' %
(item.artist, item.title))
log.error(u'No album art present in {0} - {1}.'
.format(item.artist, item.title))
return
# Add an extension to the filename.
ext = imghdr.what(None, h=art)
if not ext:
log.error('Unknown image type.')
log.error(u'Unknown image type.')
return
outpath += '.' + ext
log.info(u'Extracting album art from: {0.artist} - {0.title}\n'
u'To: {1}'.format(item, displayable_path(outpath)))
log.info(u'Extracting album art from: {0.artist} - {0.title} '
u'to: {1}'.format(item, displayable_path(outpath)))
with open(syspath(outpath), 'wb') as f:
f.write(art)
return outpath
# 'clearart' command.
def clear(lib, query):
log.info('Clearing album art from items:')
log.info(u'Clearing album art from items:')
for item in lib.items(query):
log.info(u'%s - %s' % (item.artist, item.title))
log.info(u'{0} - {1}'.format(item.artist, item.title))
try:
mf = mediafile.MediaFile(syspath(item.path),
config['id3v23'].get(bool))

View file

@ -17,7 +17,7 @@
import logging
from beets.plugins import BeetsPlugin
from beets.importer import action
from beets.library import get_query_sort
from beets.library import parse_query_string
from beets.library import Item
from beets.library import Album
@ -55,11 +55,10 @@ class IHatePlugin(BeetsPlugin):
"""
if action_patterns:
for query_string in action_patterns:
query = None
if task.is_album:
(query, _) = get_query_sort(query_string, Album)
else:
(query, _) = get_query_sort(query_string, Item)
query, _ = parse_query_string(
query_string,
Album if task.is_album else Item,
)
if any(query.match(item) for item in task.imported_items()):
return True
return False
@ -70,7 +69,7 @@ class IHatePlugin(BeetsPlugin):
if task.choice_flag == action.APPLY:
if skip_queries or warn_queries:
self._log.debug('[ihate] processing your hate')
self._log.debug(u'[ihate] processing your hate')
if self.do_i_hate_this(task, skip_queries):
task.choice_flag = action.SKIP
self._log.info(u'[ihate] skipped: {0}'
@ -80,6 +79,6 @@ class IHatePlugin(BeetsPlugin):
self._log.info(u'[ihate] you maybe hate this: {0}'
.format(summary(task)))
else:
self._log.debug('[ihate] nothing to do')
self._log.debug(u'[ihate] nothing to do')
else:
self._log.debug('[ihate] user made a decision, nothing to do')
self._log.debug(u'[ihate] user made a decision, nothing to do')

View file

@ -44,8 +44,8 @@ def write_item_mtime(item, mtime):
item's file.
"""
if mtime is None:
log.warn("No mtime to be preserved for item "
+ util.displayable_path(item.path))
log.warn(u"No mtime to be preserved for item {0}"
.format(util.displayable_path(item.path)))
return
# The file's mtime on disk must be in sync with the item's mtime
@ -64,10 +64,9 @@ def record_import_mtime(item, source, destination):
mtime = os.stat(util.syspath(source)).st_mtime
item_mtime[destination] = mtime
log.debug('Recorded mtime %s for item "%s" imported from "%s"',
mtime,
util.displayable_path(destination),
util.displayable_path(source))
log.debug(u"Recorded mtime {0} for item '{1}' imported from '{2}'".format(
mtime, util.displayable_path(destination),
util.displayable_path(source)))
@ImportAddedPlugin.listen('album_imported')

View file

@ -13,17 +13,20 @@
# included in all copies or substantial portions of the Software.
"""Write paths of imported files in various formats to ease later import in a
music player.
music player. Also allow printing the new file locations to stdout in case
one wants to manually add music to a player by its path.
"""
import datetime
import os
import re
import logging
from beets.plugins import BeetsPlugin
from beets.util import normpath, syspath, bytestring_path
from beets import config
M3U_DEFAULT_NAME = 'imported.m3u'
log = logging.getLogger('beets')
class ImportFeedsPlugin(BeetsPlugin):
@ -126,6 +129,11 @@ def _record_items(lib, basename, items):
if not os.path.exists(syspath(dest)):
os.symlink(syspath(path), syspath(dest))
if 'echo' in formats:
log.info("Location of imported music:")
for path in paths:
log.info(" " + path)
@ImportFeedsPlugin.listen('library_opened')
def library_opened(lib):

View file

@ -52,7 +52,7 @@ def run(lib, opts, args):
try:
data = data_emitter()
except mediafile.UnreadableFileError as ex:
log.error('cannot read file: {0}'.format(ex.message))
log.error(u'cannot read file: {0}'.format(ex.message))
continue
if opts.summarize:

View file

@ -64,7 +64,7 @@ def compile_inline(python_code, album):
try:
func = _compile_func(python_code)
except SyntaxError:
log.error(u'syntax error in inline field definition:\n%s' %
log.error(u'syntax error in inline field definition:\n{0}',
traceback.format_exc())
return
else:
@ -112,14 +112,14 @@ class InlinePlugin(BeetsPlugin):
# Item fields.
for key, view in itertools.chain(config['item_fields'].items(),
config['pathfields'].items()):
log.debug(u'inline: adding item field %s' % key)
log.debug(u'inline: adding item field {0}'.format(key))
func = compile_inline(view.get(unicode), False)
if func is not None:
self.template_fields[key] = func
# Album fields.
for key, view in config['album_fields'].items():
log.debug(u'inline: adding album field %s' % key)
log.debug(u'inline: adding album field {0}'.format(key))
func = compile_inline(view.get(unicode), True)
if func is not None:
self.album_template_fields[key] = func

View file

@ -67,7 +67,7 @@ def _tags_for(obj, min_weight=None):
else:
res = obj.get_top_tags()
except PYLAST_EXCEPTIONS as exc:
log.debug(u'last.fm error: %s' % unicode(exc))
log.debug(u'last.fm error: {0}'.format(exc))
return []
# Filter by weight (optionally).
@ -369,11 +369,9 @@ class LastGenrePlugin(plugins.BeetsPlugin):
if 'track' in self.sources:
item.genre, src = self._get_genre(item)
item.store()
log.info(
u'genre for track {0} - {1} ({2}): {3}'. format(
item.artist, item.title, src, item.genre
)
)
log.info(u'genre for track {0} - {1} ({2}): {3}'
.format(item.artist, item.title, src,
item.genre))
if write:
item.try_write()
@ -387,22 +385,19 @@ class LastGenrePlugin(plugins.BeetsPlugin):
album = task.album
album.genre, src = self._get_genre(album)
log.debug(u'added last.fm album genre ({0}): {1}'.format(
src, album.genre
))
src, album.genre))
album.store()
if 'track' in self.sources:
for item in album.items():
item.genre, src = self._get_genre(item)
log.debug(u'added last.fm item genre ({0}): {1}'.format(
src, item.genre
))
src, item.genre))
item.store()
else:
item = task.item
item.genre, src = self._get_genre(item)
log.debug(u'added last.fm item genre ({0}): {1}'.format(
src, item.genre
))
src, item.genre))
item.store()

View file

@ -33,10 +33,10 @@ from beets import config
log = logging.getLogger('beets')
DIV_RE = re.compile(r'<(/?)div>?')
DIV_RE = re.compile(r'<(/?)div>?', re.I)
COMMENT_RE = re.compile(r'<!--.*-->', re.S)
TAG_RE = re.compile(r'<[^>]*>')
BREAK_RE = re.compile(r'<br\s*/?>')
BREAK_RE = re.compile(r'\n?\s*<br([\s|/][^>]*)*>\s*\n?', re.I)
URL_CHARACTERS = {
u'\u2018': u"'",
u'\u2019': u"'",
@ -111,25 +111,7 @@ def extract_text(html, starttag):
print('no closing tag found!')
return
lyrics = ''.join(parts)
return strip_cruft(lyrics)
def strip_cruft(lyrics, wscollapse=True):
"""Clean up HTML from an extracted lyrics string. For example, <BR>
tags are replaced with newlines.
"""
lyrics = COMMENT_RE.sub('', lyrics)
lyrics = unescape(lyrics)
if wscollapse:
lyrics = re.sub(r'\s+', ' ', lyrics) # Whitespace collapse.
lyrics = re.sub(r'<(script).*?</\1>(?s)', '', lyrics) # Strip script tags.
lyrics = BREAK_RE.sub('\n', lyrics) # <BR> newlines.
lyrics = re.sub(r'\n +', '\n', lyrics)
lyrics = re.sub(r' +\n', '\n', lyrics)
lyrics = TAG_RE.sub('', lyrics) # Strip remaining HTML tags.
lyrics = lyrics.replace('\r', '\n')
lyrics = lyrics.strip()
return lyrics
return _scrape_strip_cruft(lyrics, True)
def search_pairs(item):
@ -140,7 +122,7 @@ def search_pairs(item):
In addition to the artist and title obtained from the `item` the
method tries to strip extra information like paranthesized suffixes
and featured artists from the strings and add them as caniddates.
and featured artists from the strings and add them as candidates.
The method also tries to split multiple titles separated with `/`.
"""
@ -264,7 +246,7 @@ def slugify(text):
text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore')
text = unicode(re.sub('[-\s]+', ' ', text))
except UnicodeDecodeError:
log.exception("Failing to normalize '%s'" % (text))
log.exception(u"Failing to normalize '{0}'".format(text))
return text
@ -294,36 +276,6 @@ def is_page_candidate(urlLink, urlTitle, title, artist):
return difflib.SequenceMatcher(None, songTitle, title).ratio() >= typoRatio
def insert_line_feeds(text):
"""Insert newlines before upper-case characters.
"""
tokensStr = re.split("([a-z][A-Z])", text)
for idx in range(1, len(tokensStr), 2):
ltoken = list(tokensStr[idx])
tokensStr[idx] = ltoken[0] + '\n' + ltoken[1]
return ''.join(tokensStr)
def sanitize_lyrics(text):
"""Clean text, returning raw lyrics as output or None if it happens
that input text is actually not lyrics content. Clean (x)html tags
in text, correct layout and syntax...
"""
text = strip_cruft(text, False)
# Restore \n in input text
if '\n' not in text:
text = insert_line_feeds(text)
while text.count('\n\n') > text.count('\n') // 4:
# Remove first occurrence of \n for each sequence of \n
text = re.sub(r'\n(\n+)', '\g<1>', text)
text = re.sub(r'\n\n+', '\n\n', text) # keep at most two \n in a row
return text
def remove_credits(text):
"""Remove first/last line of text if it contains the word 'lyrics'
eg 'Lyrics by songsdatabase.com'
@ -343,11 +295,11 @@ def is_lyrics(text, artist=None):
"""
if not text:
return
badTriggersOcc = []
nbLines = text.count('\n')
if nbLines <= 1:
log.debug("Ignoring too short lyrics '%s'" % text)
log.debug(u"Ignoring too short lyrics '{0}'".format(
text.decode('utf8')))
return 0
elif nbLines < 5:
badTriggersOcc.append('too_short')
@ -356,7 +308,7 @@ def is_lyrics(text, artist=None):
# down
text = remove_credits(text)
badTriggers = ['lyrics', 'copyright', 'property']
badTriggers = ['lyrics', 'copyright', 'property', 'links']
if artist:
badTriggersOcc += [artist]
@ -365,63 +317,58 @@ def is_lyrics(text, artist=None):
text, re.I))
if badTriggersOcc:
log.debug('Bad triggers detected: %s' % badTriggersOcc)
log.debug(u'Bad triggers detected: {0}'.format(badTriggersOcc))
return len(badTriggersOcc) < 2
def scrape_lyrics_from_url(url):
def _scrape_strip_cruft(html, plain_text_out=False):
"""Clean up HTML
"""
html = unescape(html)
# Normalize EOL
html = html.replace('\r', '\n')
html = re.sub(r' +', ' ', html) # Whitespaces collapse.
html = BREAK_RE.sub('\n', html) # <br> eats up surrounding '\n'
if plain_text_out: # Strip remaining HTML tags
html = TAG_RE.sub('', html)
html = COMMENT_RE.sub('', html)
# Strip lines
html = '\n'.join([x.strip() for x in html.strip().split('\n')])
return html
def _scrape_merge_paragraphs(html):
return re.sub(r'</p>\s*<p(\s*[^>]*)>', '\n', html)
def scrape_lyrics_from_html(html):
"""Scrape lyrics from a URL. If no lyrics can be found, return None
instead.
"""
from bs4 import BeautifulSoup, Comment
html = fetch_url(url)
from bs4 import SoupStrainer, BeautifulSoup
if not html:
return None
soup = BeautifulSoup(html)
def is_text_notcode(string):
length = len(string)
return (length > 20 and
string.count(' ') > length / 25
and (string.find('=') == -1 or string.find(';') == 1))
for tag in soup.findAll('br'):
tag.replaceWith('\n')
html = _scrape_strip_cruft(html)
html = _scrape_merge_paragraphs(html)
# Remove non relevant html parts
[s.extract() for s in soup(['head', 'script'])]
comments = soup.findAll(text=lambda text: isinstance(text, Comment))
[s.extract() for s in comments]
# extract all long text blocks that are not code
soup = BeautifulSoup(html, "html.parser",
parse_only=SoupStrainer(text=is_text_notcode))
soup = sorted(soup.stripped_strings, key=len)[-1]
try:
for tag in soup.findAll(True):
tag.name = 'p' # keep tag contents
except Exception, e:
log.debug('Error %s when replacing containing marker by p marker' % e,
exc_info=True)
# Make better soup from current soup! The previous unclosed <p> sections
# are now closed. Use str() rather than prettify() as it's more
# conservative concerning EOL
soup = BeautifulSoup(str(soup))
# In case lyrics are nested in no markup but <body>
# Insert the whole body in a <p>
bodyTag = soup.find('body')
if bodyTag:
pTag = soup.new_tag("p")
bodyTag.parent.insert(0, pTag)
pTag.insert(0, bodyTag)
tagTokens = []
for tag in soup.findAll('p'):
soup2 = BeautifulSoup(str(tag))
# Extract all text of <p> section.
tagTokens += soup2.findAll(text=True)
if tagTokens:
# Lyrics are expected to be the longest paragraph
tagTokens = sorted(tagTokens, key=len, reverse=True)
soup = BeautifulSoup(tagTokens[0])
return unescape(tagTokens[0].strip("\n\r: "))
return soup
def fetch_google(artist, title):
@ -437,7 +384,7 @@ def fetch_google(artist, title):
data = json.load(data)
if 'error' in data:
reason = data['error']['errors'][0]['reason']
log.debug(u'google lyrics backend error: %s' % reason)
log.debug(u'google lyrics backend error: {0}'.format(reason))
return
if 'items' in data.keys():
@ -446,14 +393,14 @@ def fetch_google(artist, title):
urlTitle = item['title']
if not is_page_candidate(urlLink, urlTitle, title, artist):
continue
lyrics = scrape_lyrics_from_url(urlLink)
html = fetch_url(urlLink)
lyrics = scrape_lyrics_from_html(html)
if not lyrics:
continue
lyrics = sanitize_lyrics(lyrics)
if is_lyrics(lyrics, artist):
log.debug(u'got lyrics from %s' % item['displayLink'])
log.debug(u'got lyrics from {0}'.format(item['displayLink']))
return lyrics
@ -514,8 +461,8 @@ class LyricsPlugin(BeetsPlugin):
"""
# Skip if the item already has lyrics.
if not force and item.lyrics:
log.log(loglevel, u'lyrics already present: %s - %s' %
(item.artist, item.title))
log.log(loglevel, u'lyrics already present: {0} - {1}'
.format(item.artist, item.title))
return
lyrics = None
@ -527,11 +474,11 @@ class LyricsPlugin(BeetsPlugin):
lyrics = u"\n\n---\n\n".join([l for l in lyrics if l])
if lyrics:
log.log(loglevel, u'fetched lyrics: %s - %s' %
(item.artist, item.title))
log.log(loglevel, u'fetched lyrics: {0} - {1}'
.format(item.artist, item.title))
else:
log.log(loglevel, u'lyrics not found: %s - %s' %
(item.artist, item.title))
log.log(loglevel, u'lyrics not found: {0} - {1}'
.format(item.artist, item.title))
fallback = self.config['fallback'].get()
if fallback:
lyrics = fallback
@ -553,7 +500,6 @@ class LyricsPlugin(BeetsPlugin):
if lyrics:
if isinstance(lyrics, str):
lyrics = lyrics.decode('utf8', 'ignore')
log.debug(u'got lyrics from backend: {0}'.format(
backend.__name__
))
log.debug(u'got lyrics from backend: {0}'
.format(backend.__name__))
return lyrics.strip()

View file

@ -43,7 +43,7 @@ def _missing(album):
for track_info in getattr(album_info, 'tracks', []):
if track_info.track_id not in item_mbids:
item = _item(track_info, album_info, album.id)
log.debug('{0}: track {1} in album {2}'
log.debug(u'{0}: track {1} in album {2}'
.format(PLUGIN,
track_info.track_id,
album_info.album_id))

View file

@ -313,7 +313,7 @@ class MPDStatsPlugin(plugins.BeetsPlugin):
item_types = {
'play_count': types.INTEGER,
'skip_count': types.INTEGER,
'last_played': library.Date(),
'last_played': library.DateType(),
'rating': types.FLOAT,
}

View file

@ -105,6 +105,8 @@ def play_music(lib, opts, args):
ui.print_(u'Playing {0} {1}.'.format(len(selection), item_type))
util.remove(m3u.name)
class PlayPlugin(BeetsPlugin):

View file

@ -135,7 +135,7 @@ class CommandBackend(Backend):
supported_items = filter(self.format_supported, album.items())
if len(supported_items) != len(album.items()):
log.debug('replaygain: tracks are of unsupported format')
log.debug(u'replaygain: tracks are of unsupported format')
return AlbumGain(None, [])
output = self.compute_gain(supported_items, True)
@ -198,6 +198,9 @@ class CommandBackend(Backend):
out = []
for line in text.split('\n')[1:num_lines + 1]:
parts = line.split('\t')
if len(parts) != 6 or parts[0] == 'File':
log.debug(u'replaygain: bad tool output: {0}'.format(text))
raise ReplayGainError('mp3gain failed')
d = {
'file': parts[0],
'mp3gain': int(parts[1]),
@ -577,12 +580,12 @@ class ReplayGainPlugin(BeetsPlugin):
in the item, nothing is done.
"""
if not self.track_requires_gain(item):
log.info(u'Skipping track {0} - {1}'.format(item.artist,
item.title))
log.info(u'Skipping track {0} - {1}'
.format(item.artist, item.title))
return
log.info(u'analyzing {0} - {1}'.format(item.artist,
item.title))
log.info(u'analyzing {0} - {1}'
.format(item.artist, item.title))
try:
track_gains = self.backend_instance.compute_track_gain([item])

View file

@ -59,7 +59,7 @@ class RewritePlugin(BeetsPlugin):
if fieldname not in library.Item._fields:
raise ui.UserError("invalid field name (%s) in rewriter" %
fieldname)
log.debug(u'adding template field %s' % key)
log.debug(u'adding template field {0}'.format(key))
pattern = re.compile(pattern.lower())
rules[fieldname].append((pattern, value))
if fieldname == 'artist':

View file

@ -64,7 +64,8 @@ class ScrubPlugin(BeetsPlugin):
# Walk through matching files and remove tags.
for item in lib.items(ui.decargs(args)):
log.info(u'scrubbing: %s' % util.displayable_path(item.path))
log.info(u'scrubbing: {0}'.format(
util.displayable_path(item.path)))
# Get album art if we need to restore it.
if opts.write:
@ -80,7 +81,7 @@ class ScrubPlugin(BeetsPlugin):
log.debug(u'writing new tags after scrub')
item.try_write()
if art:
log.info('restoring art')
log.info(u'restoring art')
mf = mediafile.MediaFile(item.path)
mf.art = art
mf.save()
@ -132,8 +133,7 @@ def _scrub(path):
f.save()
except IOError as exc:
log.error(u'could not scrub {0}: {1}'.format(
util.displayable_path(path),
exc,
util.displayable_path(path), exc,
))
@ -141,5 +141,5 @@ def _scrub(path):
@ScrubPlugin.listen('write')
def write_item(path):
if not scrubbing and config['scrub']['auto']:
log.debug(u'auto-scrubbing %s' % util.displayable_path(path))
log.debug(u'auto-scrubbing {0}'.format(util.displayable_path(path)))
_scrub(path)

View file

@ -42,7 +42,7 @@ def _items_for_query(lib, playlist, album=False):
query_strings = [query_strings]
model = library.Album if album else library.Item
query = dbcore.OrQuery(
[library.get_query_sort(q, model)[0] for q in query_strings]
[library.parse_query_string(q, model)[0] for q in query_strings]
)
# Execute query, depending on type.

View file

@ -63,7 +63,8 @@ class SpotifyPlugin(BeetsPlugin):
self.config['show_failures'].set(True)
if self.config['mode'].get() not in ['list', 'open']:
log.warn(self.config['mode'].get() + " is not a valid mode")
log.warn(u'{0} is not a valid mode'
.format(self.config['mode'].get()))
return False
self.opts = opts
@ -77,10 +78,10 @@ class SpotifyPlugin(BeetsPlugin):
items = lib.items(query)
if not items:
log.debug("Your beets query returned no items, skipping spotify")
log.debug(u'Your beets query returned no items, skipping spotify')
return
log.info("Processing " + str(len(items)) + " tracks...")
log.info(u'Processing {0} tracks...'.format(len(items)))
for item in items:
@ -112,7 +113,8 @@ class SpotifyPlugin(BeetsPlugin):
try:
r.raise_for_status()
except HTTPError as e:
log.debug("URL returned a " + e.response.status_code + "error")
log.debug(u'URL returned a {0} error'
.format(e.response.status_code))
failures.append(search_url)
continue
@ -128,35 +130,33 @@ class SpotifyPlugin(BeetsPlugin):
# Simplest, take the first result
chosen_result = None
if len(r_data) == 1 or self.config['tiebreak'].get() == "first":
log.debug("Spotify track(s) found, count: " + str(len(r_data)))
log.debug(u'Spotify track(s) found, count: {0}'
.format(len(r_data)))
chosen_result = r_data[0]
elif len(r_data) > 1:
# Use the popularity filter
log.debug(
"Most popular track chosen, count: " + str(len(r_data))
)
log.debug(u'Most popular track chosen, count: {0}'
.format(len(r_data)))
chosen_result = max(r_data, key=lambda x: x['popularity'])
if chosen_result:
results.append(chosen_result)
else:
log.debug("No spotify track found: " + search_url)
log.debug(u'No spotify track found: {0}'.format(search_url))
failures.append(search_url)
failure_count = len(failures)
if failure_count > 0:
if self.config['show_failures'].get():
log.info("{0} track(s) did not match a Spotify ID:".format(
failure_count
))
log.info(u'{0} track(s) did not match a Spotify ID:'
.format(failure_count))
for track in failures:
log.info("track:" + track)
log.info("")
log.info(u'track: {0}'.format(track))
log.info(u'')
else:
log.warn(
str(failure_count) + " track(s) did not match "
"a Spotify ID; use --show-failures to display\n"
)
log.warn(u'{0} track(s) did not match a Spotify ID;\n'
u'use --show-failures to display'
.format(failure_count))
return results
@ -164,7 +164,7 @@ class SpotifyPlugin(BeetsPlugin):
if results:
ids = map(lambda x: x['id'], results)
if self.config['mode'].get() == "open":
log.info("Attempting to open Spotify with playlist")
log.info(u'Attempting to open Spotify with playlist')
spotify_url = self.playlist_partial + ",".join(ids)
webbrowser.open(spotify_url)
@ -172,4 +172,4 @@ class SpotifyPlugin(BeetsPlugin):
for item in ids:
print(unicode.encode(self.open_url + item))
else:
log.warn("No Spotify tracks found from beets query")
log.warn(u'No Spotify tracks found from beets query')

View file

@ -78,19 +78,18 @@ class ZeroPlugin(BeetsPlugin):
return True
return False
def write_event(self, item):
def write_event(self, item, path, tags):
"""Listen for write event."""
if not self.patterns:
log.warn(u'[zero] no fields, nothing to do')
return
for field, patterns in self.patterns.items():
try:
value = getattr(item, field)
except AttributeError:
if field not in tags:
log.error(u'[zero] no such field: {0}'.format(field))
continue
value = tags[field]
if self.match_patterns(value, patterns):
log.debug(u'[zero] {0}: {1} -> None'.format(field, value))
setattr(item, field, None)
tags[field] = None

View file

@ -1,17 +1,63 @@
Changelog
=========
1.3.8 (in development)
1.3.9 (in development)
----------------------
This release adds **sorting** to beets queries. See :ref:`query-sort`.
Features:
* :doc:`/plugins/info`: Files can be specified through library queries
and the ``--library`` option prints library fields instead of tags.
Tags and library fields for multiple files can be summarized with the
``--summarize`` option.
* :doc:`/plugins/embedart`: You can now automatically check that new art looks
similar to existing art---ensuring that you only get a better "version" of
the art you already have. See :ref:`image-similarity-check`.
* Re-imports of your existing music (see :ref:`reimport`) now preserve its
added date and flexible attributes. Thanks to Stig Inge Lea Bjørnsen.
* :doc:`/plugins/bpd`: Add a new configuration option for setting the default
volume. Thanks to IndiGit.
Fixes:
* :doc:`/plugins/convert`: Does not crash when embedding cover art
fails.
* :doc:`/plugins/mpdstats`: Fix an error on start (introduced in the previous
version). Thanks to Zach Denton.
* :doc:`/plugins/convert`: The ``--yes`` command-line flag no longer expects
an argument.
* :doc:`/plugins/play`: Remove the temporary .m3u file after sending it to
the player.
* The importer no longer tries to highlight partial differences in numeric
quantities (track numbers and durations), which was often confusing.
* Date-based queries that are malformed (not parse-able) no longer crash
beets and instead fail silently.
1.3.8 (September 17, 2014)
--------------------------
This release has two big new chunks of functionality. Queries now support
**sorting** and user-defined fields can now have **types**.
If you want to see all your songs in reverse chronological order, just type
``beet list year-``. It couldn't be easier. For details, see
:ref:`query-sort`.
Flexible field types mean that some functionality that has previously only
worked for built-in fields, like range queries, can now work with plugin- and
user-defined fields too. For starters, the :doc:`/plugins/echonest/` and
:doc:`/plugins/mpdstats` now mark the types of the fields they provide---so
you can now say, for example, ``beet ls liveness:0.5..1.5`` for the Echo Nest
"liveness" attribute. The :doc:`/plugins/types` makes it easy to specify field
types in your config file.
One upgrade note: if you use the :doc:`/plugins/discogs`, you will need to
upgrade the Discogs client library to use this version. Just type
``pip install -U discogs-client``.
Other new features:
* :doc:`/plugins/info`: Target files can now be specified through library
queries (in addition to filenames). The ``--library`` option prints library
fields instead of tags. Multiple files can be summarized together with the
new ``--summarize`` option.
* :doc:`/plugins/mbcollection`: A new option lets you automatically update
your collection on import. Thanks to Olin Gay.
* :doc:`/plugins/convert`: A new ``never_convert_lossy_files`` option can
@ -19,7 +65,7 @@ Features:
* :doc:`/plugins/convert`: A new ``--yes`` command-line flag skips the
confirmation.
Fixes:
Still more fixes and little improvements:
* Invalid state files don't crash the importer.
* :doc:`/plugins/lyrics`: Only strip featured artists and
@ -49,6 +95,17 @@ Fixes:
* The ``--version`` flag now works as an alias for the ``version`` command.
* :doc:`/plugins/lastgenre`: Remove some unhelpful genres from the default
whitelist. Thanks to gwern.
* :doc:`/plugins/importfeeds`: A new ``echo`` output mode prints files' paths
to standard error. Thanks to robotanarchy.
* :doc:`/plugins/replaygain`: Restore some error handling when ``mp3gain``
output cannot be parsed. The verbose log now contains the bad tool output in
this case.
* :doc:`/plugins/convert`: Fix filename extensions when converting
automatically.
* The ``write`` plugin event allows plugins to change the tags that are
written to a media file.
* :doc:`/plugins/zero`: Do not delete database values; only media file
tags are affected.
.. _discogs_client: https://github.com/discogs/discogs_client

View file

@ -12,7 +12,7 @@ project = u'beets'
copyright = u'2012, Adrian Sampson'
version = '1.3'
release = '1.3.8'
release = '1.3.9'
pygments_style = 'sphinx'

View file

@ -143,11 +143,14 @@ currently available are:
or album's part) is removed from the library (even when its file is not
deleted from disk).
* *write*: called with an ``Item`` object just before a file's metadata is
written to disk (i.e., just before the file on disk is opened). Event
handlers may raise a ``library.FileOperationError`` exception to abort
the write operation. Beets will catch that exception, print an error
message and continue.
* *write*: called with an ``Item`` object, a ``path``, and a ``tags``
dictionary just before a file's metadata is written to disk (i.e.,
just before the file on disk is opened). Event handlers may change
the ``tags`` dictionary to customize the tags that are written to the
media file. Event handlers may also raise a
``library.FileOperationError`` exception to abort the write
operation. Beets will catch that exception, print an error message
and continue.
* *after_write*: called with an ``Item`` object after a file's metadata is
written to disk (i.e., just after the file on disk is closed).
@ -403,8 +406,9 @@ Flexible Field Types
^^^^^^^^^^^^^^^^^^^^
If your plugin uses flexible fields to store numbers or other
non-string values you can specify the types of those fields. A rating
plugin, for example might look like this. ::
non-string values, you can specify the types of those fields. A rating
plugin, for example, might want to declare that the ``rating`` field
should have an integer type::
from beets.plugins import BeetsPlugin
from beets.dbcore import types
@ -416,18 +420,18 @@ plugin, for example might look like this. ::
def album_types(self):
return {'rating': types.INTEGER}
A plugin may define two attributes, `item_types` and `album_types`.
A plugin may define two attributes: `item_types` and `album_types`.
Each of those attributes is a dictionary mapping a flexible field name
to a type instance. You can find the built-in types in the
`beets.dbcore.types` and `beets.library` modules or implement your own
ones.
type by inheriting from the `Type` class.
Specifying types has the following advantages.
Specifying types has several advantages:
* The flexible field accessors ``item['my_field']`` return the
specified type instead of a string.
* Code that accesses the field like ``item['my_field']`` gets the right
type (instead of just a string).
* Users can use advanced queries (like :ref:`ranges <numericquery>`)
* You can use advanced queries (like :ref:`ranges <numericquery>`)
from the command line.
* User input for flexible fields may be validated.
* User input for flexible fields may be validated and converted.

View file

@ -71,12 +71,14 @@ on your headless server box. Rad!
To configure the BPD server, add a ``bpd:`` section to your ``config.yaml``
file. The configuration values, which are pretty self-explanatory, are ``host``,
``port``, and ``password``. Here's an example::
``port``, ``password`` and ``volume``. The volume option sets the initial
volume (in percent, default: 100). Here's an example::
bpd:
host: 127.0.0.1
port: 6600
password: seekrit
volume: 100
Implementation Notes
--------------------

View file

@ -19,6 +19,26 @@ embedded after each album is added to the library.
This behavior can be disabled with the ``auto`` config option (see below).
.. _image-similarity-check:
Image Similarity
''''''''''''''''
When importing a lot of files with the ``auto`` option, one may be reluctant to
overwrite existing embedded art for all of them.
You can tell beets to avoid embedding images that are too different from the
This works by computing the perceptual hashes (`PHASH`_) of the two images and
checking that the difference between the two does not exceed a
threshold. You can set the threshold with the ``compare_threshold`` option.
A threshold of 0 (the default) disables similarity checking and always embeds
new images. Set the threshold to another number---we recommend between 10 and
100---to adjust the sensitivity of the comparison. The smaller the threshold
number, the more similar the images must be.
This feature requires `ImageMagick`_.
Manually Embedding and Extracting Art
-------------------------------------
@ -53,7 +73,13 @@ before embedding them (the original image file is not altered). The resize
operation reduces image width to ``maxwidth`` pixels. The height is recomputed
so that the aspect ratio is preserved. `PIL`_ or `ImageMagick`_ is required to
use the ``maxwidth`` config option. See also :ref:`image-resizing` for further
caveats about image resizing.
so that the aspect ratio is preserved.
The ``compare_threshold`` option defines how similar must candidate art be
regarding to embedded art to be written to the file (see
:ref:`image-similarity-check`). The default is 0 (no similarity check).
Requires `ImageMagick`_.
.. _PIL: http://www.pythonware.com/products/pil/
.. _ImageMagick: http://www.imagemagick.org/
.. _PHASH: http://www.fmwconcepts.com/misc_tests/perceptual_hash_test_results_510/

View file

@ -18,12 +18,13 @@ root of your music library.
The ``absolute_path`` configuration option can be set to use absolute paths
instead of relative paths. Some applications may need this to work properly.
Three different types of outputs coexist, specify the ones you want to use by
setting the ``formats`` parameter:
Four different types of outputs are available. Specify the ones you want to
use by setting the ``formats`` parameter:
- ``m3u``: catalog the imports in a centralized playlist. By default, the playlist is named ``imported.m3u``. To use a different file, just set the ``m3u_name`` parameter inside the ``importfeeds`` config section.
- ``m3u_multi``: create a new playlist for each import (uniquely named by appending the date and track/album name).
- ``link``: create a symlink for each imported item. This is the recommended setting to propagate beets imports to your iTunes library: just drag and drop the ``dir`` folder on the iTunes dock icon.
- ``echo``: do not write a playlist file at all, but echo a list of new file paths to the terminal.
Here's an example configuration for this plugin::

View file

@ -4,14 +4,14 @@ Types Plugin
The ``types`` plugin lets you declare types for attributes you use in your
library. For example, you can declare that a ``rating`` field is numeric so
that you can query it with ranges---which isn't possible when the field is
considered a string, which is the default.
considered a string (the default).
Enable the plugin as described in :doc:`/plugins/index` and then add a
``types`` section to your :doc:`configuration file </reference/config>`. The
configuration section should map field name to one of ``int``, ``float``,
``bool``, or ``date``.
Here's an example:
Here's an example::
types:
rating: int

View file

@ -132,6 +132,8 @@ Optional command flags:
.. only:: html
.. _reimport:
Reimporting
^^^^^^^^^^^

View file

@ -193,18 +193,16 @@ option overrides this setting.
sort_item
~~~~~~~~~
Sort order to use when listing *individual items* with the :ref:`list-cmd`
command and other commands that need to print out items. Defaults to
``smartartist+``. Any command-line sort order overrides this setting.
Default sort order to use when fetching items from the database. Defaults to
``artist+ album+ disc+ track+``. Explicit sort orders override this default.
.. _sort_album:
sort_album
~~~~~~~~~~
Sort order to use when listing *albums* with the :ref:`list-cmd`
command. Defaults to ``smartartist+``. Any command-line sort order overrides
this setting.
Default sort order to use when fetching items from the database. Defaults to
``albumartist+ album+``. Explicit sort orders override this default.
.. _original_date:

View file

@ -190,25 +190,23 @@ ones you've already added to your beets library.
Sort Order
----------
You can also specify the order used when outputting the results. Of course, this
is only useful when displaying the result, for example with the ``list``
command, and is useless when the query is used as a filter for an command. Use
the name of the `field` you want to sort on, followed by a ``+`` or ``-`` sign
if you want ascending or descending sort. For example this command::
Queries can specify a sort order. Use the name of the `field` you want to sort
on, followed by a ``+`` or ``-`` sign to indicate ascending or descending
sort. For example, this command::
$ beet list -a year+
will list all albums in chronological order.
There is a special ``smartartist`` sort that uses sort-specific field (
``artist_sort`` for items and ``albumartist_sort`` for albums) but falls back to
standard artist fields if these are empty. When no sort order is specified,
``smartartist+`` is used (but this is configurable).
You can also specify several sort orders, which will be used in the same order at
which they appear in your query::
will list all albums in chronological order. You can also specify several sort
orders, which will be used in the same order as they appear in your query::
$ beet list -a genre+ year+
This command will sort all albums by genre and, in each genre, in chronological
order.
The ``artist`` and ``albumartist`` keys are special: they attempt to use their
corresponding ``artist_sort`` and ``albumartist_sort`` fields for sorting
transparently (but fall back to the ordinary fields when those are empty).
You can set the default sorting behavior with the :ref:`sort_item` and
:ref:`sort_album` configuration options.

View file

@ -55,7 +55,7 @@ VERSION_LOCS = [
os.path.join(BASE, 'setup.py'),
[
(
r'version\s*=\s*[\'"]([0-9\.]+)[\'"]',
r'\s*version\s*=\s*[\'"]([0-9\.]+)[\'"]',
" version='{version}',",
)
]
@ -77,6 +77,7 @@ def bump_version(version):
# Read and transform the file.
out_lines = []
with open(filename) as f:
found = False
for line in f:
for pattern, template in locations:
match = re.match(pattern, line)
@ -96,12 +97,16 @@ def bump_version(version):
minor=minor,
) + '\n')
found = True
break
else:
# Normal line.
out_lines.append(line)
if not found:
print("No pattern found in {}".format(filename))
# Write the file back.
with open(filename, 'w') as f:
f.write(''.join(out_lines))
@ -180,6 +185,9 @@ def changelog_as_markdown():
# Other backslashes with verbatim ranges.
rst = re.sub(r'(\s)`([^`]+)`([^_])', r'\1``\2``\3', rst)
# Command links with command names.
rst = re.sub(r':ref:`(\w+)-cmd`', r'``\1``', rst)
return rst2md(rst)

View file

@ -45,7 +45,7 @@ if 'sdist' in sys.argv:
setup(
name='beets',
version='1.3.8',
version='1.3.9',
description='music tagger and library organizer',
author='Adrian Sampson',
author_email='adrian@radbox.org',

View file

@ -35,6 +35,7 @@ import os
import os.path
import shutil
import subprocess
import logging
from tempfile import mkdtemp, mkstemp
from contextlib import contextmanager
from StringIO import StringIO
@ -52,6 +53,27 @@ from beets.mediafile import MediaFile
import _common
class LogCapture(logging.Handler):
def __init__(self):
logging.Handler.__init__(self)
self.messages = []
def emit(self, record):
self.messages.append(str(record.msg))
@contextmanager
def capture_log(logger='beets'):
capture = LogCapture()
log = logging.getLogger(logger)
log.addHandler(capture)
try:
yield capture.messages
finally:
log.removeHandler(capture)
@contextmanager
def control_stdin(input=None):
"""Sends ``input`` to stdin.

View file

@ -1,185 +0,0 @@
# This file is part of beets.
# Copyright 2014, Fabrice Laporte.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
"""Tests for the 'lyrics' plugin"""
import os
import logging
import _common
from _common import unittest
from beetsplug import lyrics
from beets import config
from beets.util import confit
from bs4 import BeautifulSoup
log = logging.getLogger('beets')
LYRICS_TEXTS = confit.load_yaml(os.path.join(_common.RSRC, 'lyricstext.yaml'))
try:
googlekey = config['lyrics']['google_API_key'].get(unicode)
except confit.NotFoundError:
googlekey = None
# default query for tests
definfo = dict(artist=u'The Beatles', title=u'Lady Madonna')
class MockFetchUrl(object):
def __init__(self, pathval='fetched_path'):
self.pathval = pathval
self.fetched = None
def __call__(self, url, filename=None):
self.fetched = url
url = url.replace('http://', '').replace('www.', '')
fn = "".join(x for x in url if (x.isalnum() or x == '/'))
fn = fn.split('/')
fn = os.path.join('rsrc', 'lyrics', fn[0], fn[-1]) + '.txt'
with open(fn, 'r') as f:
content = f.read()
return content
def is_lyrics_content_ok(title, text):
"""Compare lyrics text to expected lyrics for given title"""
setexpected = set(LYRICS_TEXTS[lyrics.slugify(title)].split())
settext = set(text.split())
setinter = setexpected.intersection(settext)
# consider lyrics ok if they share 50% or more with the reference
if len(setinter):
ratio = 1.0 * max(len(setexpected), len(settext)) / len(setinter)
return (ratio > .5 and ratio < 2)
return False
class LyricsPluginTest(unittest.TestCase):
def setUp(self):
"""Set up configuration"""
lyrics.LyricsPlugin()
def test_default_ok(self):
"""Test each lyrics engine with the default query"""
lyrics.fetch_url = MockFetchUrl()
for f in (lyrics.fetch_lyricswiki, lyrics.fetch_lyricscom):
res = f(definfo['artist'], definfo['title'])
self.assertTrue(lyrics.is_lyrics(res))
self.assertTrue(is_lyrics_content_ok(definfo['title'], res))
def test_missing_lyrics(self):
self.assertFalse(lyrics.is_lyrics(LYRICS_TEXTS['missing_texts']))
class LyricsScrapingPluginTest(unittest.TestCase):
# Every source entered in default beets google custom search engine
# must be listed below.
# Use default query when possible, or override artist and title field
# if website don't have lyrics for default query.
sourcesOk = [
dict(definfo, url=u'http://www.smartlyrics.com',
path=u'/Song18148-The-Beatles-Lady-Madonna-lyrics.aspx'),
dict(definfo, url=u'http://www.elyricsworld.com',
path=u'/lady_madonna_lyrics_beatles.html'),
dict(artist=u'Beres Hammond', title=u'I could beat myself',
url=u'http://www.reggaelyrics.info',
path=u'/beres-hammond/i-could-beat-myself'),
dict(definfo, artist=u'Lilly Wood & the prick', title=u"Hey it's ok",
url=u'http://www.lyricsmania.com',
path=u'/hey_its_ok_lyrics_lilly_wood_and_the_prick.html'),
dict(definfo, artist=u'Lilly Wood & the prick', title=u"Hey it's ok",
url=u'http://www.paroles.net/',
path=u'lilly-wood-the-prick/paroles-hey-it-s-ok'),
dict(definfo, artist=u'Amy Winehouse', title=u"Jazz'n'blues",
url=u'http://www.lyricsontop.com',
path=u'/amy-winehouse-songs/jazz-n-blues-lyrics.html'),
dict(definfo, url=u'http://www.sweetslyrics.com',
path=u'/761696.The%20Beatles%20-%20Lady%20Madonna.html'),
dict(definfo, url=u'http://www.lyrics007.com',
path=u'/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html'),
dict(definfo, url=u'http://www.absolutelyrics.com',
path=u'/lyrics/view/the_beatles/lady_madonna'),
dict(definfo, url=u'http://www.azlyrics.com/',
path=u'/lyrics/beatles/ladymadonna.html'),
dict(definfo, url=u'http://www.chartlyrics.com',
path=u'/_LsLsZ7P4EK-F-LD4dJgDQ/Lady+Madonna.aspx'),
dict(definfo, url='http://www.releaselyrics.com',
path=u'/e35f/the-beatles-lady-madonna'),
]
# Websites that can't be scraped yet and whose results must be
# flagged as invalid lyrics.
sourcesFail = [
dict(definfo, url='http://www.songlyrics.com',
path=u'/the-beatles/lady-madonna-lyrics'),
dict(definfo, url='http://www.metrolyrics.com/',
path='best-for-last-lyrics-adele.html')
]
# Websites that return truncated lyrics because of scraping issues, and
# thus should not be included as sources to Google CSE.
# They are good candidates for later inclusion after improvement
# iterations of the scraping algorithm.
sourcesIncomplete = [
dict(definfo, artist=u'Lilly Wood & the prick', title=u"Hey it's ok",
url=u'http://www.lacoccinelle.net',
path=u'/paroles-officielles/550512.html'),
]
def test_sources_ok(self):
for s in self.sourcesOk:
url = s['url'] + s['path']
res = lyrics.scrape_lyrics_from_url(url)
self.assertTrue(lyrics.is_lyrics(res), url)
self.assertTrue(is_lyrics_content_ok(s['title'], res), url)
def test_sources_fail(self):
for s in self.sourcesFail:
url = s['url'] + s['path']
res = lyrics.scrape_lyrics_from_url(url)
# very unlikely these sources pass if the scraping algo is not
# tweaked on purpose for these cases
self.assertFalse(lyrics.is_lyrics(res), "%s => %s" % (url, res))
def test_sources_incomplete(self):
for s in self.sourcesIncomplete:
url = s['url'] + s['path']
res = lyrics.scrape_lyrics_from_url(url)
self.assertTrue(lyrics.is_lyrics(res))
# these sources may pass if the html source evolve or after
# a random improvement in the scraping algo: we want to
# be noticed if it's the case.
if is_lyrics_content_ok(s['title'], res):
log.debug('Source %s actually return valid lyrics!' % s['url'])
def test_is_page_candidate(self):
for s in self.sourcesOk:
url = unicode(s['url'] + s['path'])
html = lyrics.fetch_url(url)
soup = BeautifulSoup(html)
if not soup.title:
continue
self.assertEqual(lyrics.is_page_candidate(url, soup.title.string,
s['title'], s['artist']),
True, url)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)
if __name__ == '__main__':
unittest.main(defaultTest='suite')

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
test/rsrc/abbey-similar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
test/rsrc/abbey.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -267,6 +267,10 @@
<div id="related_artists">
<div id="ratitle">Latest Beatles Lyrics</div>
<a href="http://www.elyricsworld.com/let's_twist_again_lyrics_beatles.html">Let's Twist Again Lyrics</a>
<a href="http://www.elyricsworld.com/little_child_(mono)_lyrics_beatles.html">Little Child (mono) Lyrics</a>
<a href="http://www.elyricsworld.com/be-bop-a-lula_(live)_lyrics_beatles.html">BE-BOP-A-LULA (Live) Lyrics</a>
<a href="http://www.elyricsworld.com/reminiscing_(live)_lyrics_beatles.html">REMINISCING (Live) Lyrics</a>
@ -282,10 +286,6 @@
<a href="http://www.elyricsworld.com/while_my_guitar_genly_weeps_lyrics_beatles.html">While My Guitar Genly Weeps Lyrics</a>
<a href="http://www.elyricsworld.com/strawberry_field_forever_(emi-remix_15.12.66)_lyrics_beatles.html">Strawberry Field Forever (Emi-remix 15.12.66) Lyrics</a>
<a href="http://www.elyricsworld.com/step_inside_love_lyrics_beatles.html">Step Inside Love Lyrics</a>
<a href="http://www.elyricsworld.com/it_came_upon_midnight_clear_(babys_in_black)_lyrics_beatles.html">It Came Upon Midnight Clear (Babys In Black) Lyrics</a>
</div>
</div>
<div id="pright">
@ -440,7 +440,6 @@ click: function(score, evt) {
</div>
<div id="panel_in" style="padding-left:9px;">
<object width="279" height="193"><param name="movie" value="http://www.youtube.com/v/VfthrizXKOM&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/VfthrizXKOM&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="280" height="193"></embed></object>
<div style="width:300px; margin-top:5px;">Embed Video <input onclick="select();" value="&lt;div style=&quot;text-align:center;width:302px;height:220px;&quot;&gt;&lt;object width=&quot;300&quot; height=&quot;193&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/VfthrizXKOM&amp;amp;hl=en_US&amp;amp;fs=1&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/VfthrizXKOM&amp;amp;hl=en_US&amp;amp;fs=1&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;300&quot; height=&quot;193&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br&gt;&lt;a href=&quot;http://www.elyricsworld.com/lady_madonna_lyrics_beatles.html&quot;&gt;Lady Madonna Lyrics&lt;/a&gt; at elw&lt;/div&gt;" style="width: 276px;" readonly="readonly" type="text"></div>
</div>
</div>
<div id="artist_panel_l" style="margin-top:20px; margin-bottom:10px;">
@ -450,14 +449,6 @@ click: function(score, evt) {
</div>
<div id="panel_in" style="padding-left:9px;">
<embed src='http://widget.elyricsworld.com/scroller.swf?lid=154160&speed=4' width='280' height='160' type='application/x-shockwave-flash'/></embed></object>
<div style="width:300px; margin-top:5px;">Embed Widget <input onclick="select();" value="&lt;div style='font-size:10px; font-family: Verdana, Tahoma, Sans-serif; line-height:10px; width:300px;'&gt;
&lt;object width='300' height='175'&gt;
&lt;embed src='http://widget.elyricsworld.com/scroller.swf?lid=154160&amp;speed=4'
width='300' height='175' type='application/x-shockwave-flash'/&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;br /&gt;&lt;center&gt;&lt;a href='http://www.elyricsworld.com/lady_madonna_lyrics_beatles.html' target='_blank'&gt;Lady Madonna&lt;/a&gt;
found at &lt;a href='http://www.elyricsworld.com' target='_blank'&gt;elyricsworld.com&lt;/a&gt;&lt;/center&gt;
&lt;/div&gt;" style="width: 276px;" readonly="readonly" type="text"></div>
</div>
</div>
<div id="banner_rr2">
@ -532,4 +523,4 @@ found at &lt;a href='http://www.elyricsworld.com' target='_blank'&gt;elyricsworl
</noscript>
<!-- End comScore Tag -->
</body>
</html>
</html>

View file

@ -0,0 +1,712 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Paroles et traduction Jacques Brel : Amsterdam - paroles de chanson</title>
<meta name="description" content="Jacques Brel : Amsterdam paroles et traduction de la chanson "/>
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"/><![endif]-->
<link href="/s.css?1410808470" rel="stylesheet" type="text/css" title="default"/>
<link rel="icon" type="image/gif" href="/favicon.gif?1410808470"/>
<script type="text/javascript" src="/g.js?1410808470"></script><script type="text/javascript" src="/summary.js?1410808470"></script>
<script type="text/javascript"><!--
dwService.reload = false;
dwService.setTargetings({"pagId":"1647","pagType":"content","layId":"550","directories":["\/"],"conId":"275679","appId":"4762"});
initGA(['UA-4587199-1', 'UA-26394066-3']);
initXiti(175975);//-->
</script>
<link rel="image_src" href="/593869-2544.jpg?20120608"/>
</head>
<body id="layout550" class="dom1 contentPage cdir app4762 status3">
<div id="contener">
<div id="header-background">
<div id="header">
<div id="header-content">
<div class="header"></div>
<!--Ht@7076--><div class="headerLogo"><a href="/index.html"><img src="/logo-2013.png?1410808470" width="200" height="64" alt="Accueil paroles de chansons"/></a>
</div><!--/Ht@7076--><!--LoBo@4755--><div class="zoneLogin"><div id="loginBoxLogged" style="display:none" class="loginBox">
<a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', null);
return false">Mon compte <span id="loginBox_numbers_" class="number"></span></a>
<a href="#" title="Déconnexion" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.logout();
return false;"><img src="/iconlogout.png?1410808470" alt=""/></a>
<table id="loginBoxMenuLogged">
<tr>
<td>
<a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('account');
return false;">
<span id="loginBox_mediumavatar_"></span><br/><br/>
<span id="loginBox_pseudo_"></span>
</a>
</td>
<td>
<table>
<tr>
<td><img src="/iconmessage.png?1410808470" alt=""/><span id="loginBox_msg_" class="number"></span></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('message');
return false;">Mes messages</a></td>
</tr>
<tr>
<td><img src="/iconnotifications.png?1410808470" alt=""/><span id="loginBox_notif_" class="number"></span></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('notifications');
return false;" >Mes notifications</a></td>
</tr>
<tr>
<td><img src="/iconfriends.png?1410808470" alt=""/><span id="loginBox_fr_" class="number"></span></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('friends');
return false;">Mes amis</a></td>
</tr>
<tr>
<td><img src="/iconmypage.png?1410808470" alt=""/></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('user');
return false;">Ma page personnelle</a></td>
</tr>
<tr>
<td><img src="/icontools.png?1410808470" alt=""/></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('account');
return false;">Mes paramètres</a></td>
</tr>
<tr>
<td><img src="/iconfolder.png?1410808470" alt=""/></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go();
return false;">Mes contenus</a></td>
</tr>
<tr>
<td><img src="/iconfavorites.png?1410808470" alt=""/></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwLightBox.cache = true;
dwLightBox.open('Mes contenus favoris', dwService.getUrl('s', 'contents.favorites'), 'ajax');
return false;">Mes contenus favoris</a></td>
</tr>
<tr>
<td><img src="/iconadd.png?1410808470" alt=""/></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('content');
return false;">Ajouter un contenu</a></td>
</tr>
<tr style="display:none" id="loginBox_row_editcontent_">
<td><img src="/iconedit.png?1410808470" alt=""/></td>
<td><a href="#" id="loginBox_editcontent_">Éditer ce contenu</a></td>
</tr>
<tr style="display:none">
<td><img src="/iconcredits.png?1410808470" alt=""/><span id="loginBox_crd_" class="number"></span></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('credit');
return false;">Mes crédits</a></td>
</tr>
<tr style="display:none">
<td><img src="/iconorders.png?1410808470" alt=""/></td>
<td><a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('orders');
return false;">Mes commandes</a></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div id="loginBoxNotLogged" class="loginBox">
<a href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', null);
return false">Mon compte</a>
<table id="loginBoxMenuNotLogged">
<tr>
<td>
<a href="#" title="Connexion" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwUser.login();
return false;">Connexion</a>
</td>
</tr>
<tr>
<td>
<a href="#" title="Inscription" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwService.open('register', 'Inscription');
return false;">Inscription</a>
</td>
</tr>
<tr>
<td>
<a id="facebook-connect" href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwUser.loginFrom('facebook', 'www.lacoccinelle.net');
return false;"><span>Connexion via Facebook</span></a>
</td>
</tr>
<tr>
<td>
<a id="twitter-connect" href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwUser.loginFrom('twitter', 'www.lacoccinelle.net');
return false;"><span>Connexion via Twitter</span></a>
</td>
</tr>
<tr>
<td>
<a id="google-connect" href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwUser.loginFrom('google', 'www.lacoccinelle.net');
return false;"><span>Connexion via Google+</span></a>
</td>
</tr>
<tr>
<td>
<a id="live-connect" href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwUser.loginFrom('live', 'www.lacoccinelle.net');
return false;"><span>Connexion via Windows Live</span></a>
</td>
</tr>
<tr>
<td>
<a id="openid-connect" href="#" onclick="dwElement.setDisplayStyle('loginBoxMenuNotLogged', false);
dwUser.loginFrom('openid', 'www.lacoccinelle.net');
return false;"><span>Connexion via OpenID</span></a>
</td>
</tr>
</table>
</div>
<script type="text/javascript"><!--
dwUser.displayIfLogged('loginBoxLogged', 'loginBoxNotLogged');
dwUser.displayIfLogged('loginBox_numbers_');
dwUser.displayIfLogged('loginBox_mediumavatar_');
dwUser.displayIfLogged('loginBox_pseudo_');
dwUser.displayIfLogged('loginBox_msg_');
dwUser.displayIfLogged('loginBox_fr_');
dwUser.displayIfLogged('loginBox_notif_');
dwUser.displayIfLogged('loginBox_crd_');
var m = document.location.href.match(/\/(\d+)\.html/);
if (m && m[1] && document.location.href.indexOf('/m/') === -1)
{
dwElement.setDisplayStyle('loginBox_row_editcontent_', true);
dwElement.get('loginBox_editcontent_').onclick = function()
{
dwElement.setDisplayStyle('loginBoxMenuLogged', false);
dwUser.go('content', m[1]);
return false;
};
}//-->
</script></div><!--/LoBo@4755--><!--Ht@7075--><div class="headerMenu"><table cellpadding="0" cellspacing="0">
<tr>
<td><a href="/index.html">CHANSONS</a></td>
<td><a href="/artistes/index.html">ARTISTES</a></td>
<td><a href="/albums/index.html">ALBUMS</a></td>
<td><a href="/paroles-officielles/index.html">PAROLES OFFICIELLES</a></td>
</tr>
</table>
</div><!--/Ht@7075--><!--Ht@7077--><div class="headerTitle"><img src="/home-title.png?1410808470" width="693" height="110" alt="Paroles de chansons, traductions, explications"/>
</div><!--/Ht@7077--><!--SeFo@7074--><div class="headerSearch">
<form action="/s.html" method="post" id="searchForm-7074" onsubmit="return dwSearch.send(this.id);">
<p>
<span class="searchForm">
<input type="text" name="q" id="searchForm-7074-q" size="15" alt="Rechercher une chanson, un artiste..." value="Rechercher une chanson, un artiste..." onfocus="if (typeof (dwSearch.d['searchForm-7074']) === 'undefined' || dwSearch.d['searchForm-7074'] === this.value) this.value = ''; dwSearch.suggestKey(7074, event);" onkeydown="return dwSearch.suggestKey(7074, event);" onkeyup="dwUtils.runOnce('search-7074', function() { dwSearch.suggest(7074)}, 500); return false;" onblur="dwSearch.suggestHide(7074);"/><a href="#" onclick="if (dwSearch.send('searchForm-7074') === true) dwElement.get('searchForm-7074').submit(); return false;"><img id="searchForm-7074-default" src="/spacer.gif?1410808470" alt="Rechercher une chanson, un artiste..."/></a>
</span>
<input type="submit" style="display:none"/><!-- affiché uniquement pour qu'en tapant sur entrée dans un champ ça POST le formulaire -->
</p>
<div id="searchForm-7074-suggestions" class="search-suggests" style="display:none"></div>
<div id="searchForm-7074-message" style="display:none"></div>
</form>
<script type="text/javascript"><!--
dwAjax.setMessages('searchForm-7074', {1: 'Veuillez entrer au moins un mot-clé de recherche'});
dwSearch.restore('searchForm-7074');
dwSearch.suggestInit(7074, '4748,4762,5873,5935', 10); //-->
</script>
</div><!--/SeFo@7074--><!--Ht@4808--><div class="pub728"><script type="text/javascript"><!--
SmartAdServerAjax(document.location.pathname==='/index.html'?'2301/378531':'2301/16363',438,'','ww62.smartadserver.com');//-->
</script>
</div><!--/Ht@4808-->
<div class="footer"></div>
</div>
</div>
</div>
<div id="body-background">
<div id="body-header"></div>
<div id="body">
<div id="body-content">
<div id="clr-z1" class="clr-zone">&nbsp;</div>
<div id="zone1"><div class="header"></div><div id="subzone1"><!--Ht@4807--><div class="pub300"><script type="text/javascript"><!--
SmartAdServerAjax(document.location.pathname==='/index.html'?'2301/378531':'2301/16363',439,'','ww62.smartadserver.com');//-->
</script>
</div><!--/Ht@4807--><!--LiCoDe@7092--><div class="box boxList" id="block7092"><div class="list">
<h4 class="label">Coup de projecteur sur...</h4>
<div class="contents" id="contener7092" style="position:relative;z-index:0;">
<div id="contener7092-0" class="contener" style="width:100%;position:absolute;z-index:0;background-image:url(/1003290-3181.jpg?20140325);background-repeat:no-repeat">
<div class="title"><div class="inner">
<a href="/albums/910041.html">Mue, le nouvel album d'Emilie Simon</a></div></div>
</div>
</div>
</div>
<script type="text/javascript"><!--
dwSummary.init(7092, 1); //-->
</script>
</div><!--/LiCoDe@7092--><!--Ht@4840--><div class="box facebox"><h4>Facebook / Soirées</h4>
<div id="facebookIframe"></div><div id="soonnightIframe"></div>
<script type="text/javascript"><!--
dwElement.addEvent(null, 'load', function()
{
dwElement.setValue('facebookIframe', '<i' + 'frame src="http://www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Flacoccinelle.net&amp;width=288&amp;colorscheme=light&amp;show_faces=false&amp;stream=false&amp;header=false&amp;height=70" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:288px; height:70px;" allowTransparency="true"></i' + 'frame>');
// SoonNight
dwElement.setValue('soonnightIframe', '<i' + 'frame src="http://www.soonnight.com/agenda/agenda,1039.html?r=1&amp;url_page=http://www.soonnight.com&amp;color=white&amp;go_soonnight=1" width="273" height="150" scrolling="no" frameborder="0"></ifr' + 'ame>');
}); //-->
</script>
</div><!--/Ht@4840--><!--AdDFP@6638--><div class="pub300"><script type="text/javascript"><!--
dwService.dfpFillSlot("6638-300x600",300,600); //-->
</script><!-- dfp@0 --></div><!--/AdDFP@6638--><!--Ht@7154--><div class="box facebox"><h4>Pour les pitchouns</h4>
<div style="padding:5px 15px 0">
<a href="http://www.patabulle.fr/" onclick="dwDocument.openWindow(this.href);return false" style="display:block;line-height:0"><img src="https://tpc.googlesyndication.com/pagead/imgad?id=CICAgKDjmdujJRCMAhjfASgBMggnwqrh7aV2bQ" width="268" height="223" alt="Patabulle - Livre et vidéos pour enfants" style="vertical-align:middle"/></a>
</div>
</div><!--/Ht@7154--></div><div class="footer"></div></div>
<div id="clr-z2" class="clr-zone">&nbsp;</div>
<div id="zone2"><div class="header"></div><div id="subzone2"><!--PaFi@6710--><div class="breadcrumb">
<div id="breadcrumb" class="dwBreadcrumb"><a href="/index.html" title="Accueil">Accueil</a> &gt; <a href="/216466.html" title="Jacques Brel">Jacques Brel</a> &gt; <a href="/233206.html" title="Live Olympia 1964">Live Olympia 1964</a> </div></div><!--/PaFi@6710--><!--CoSo@4762--><div><div id="content275679" class="content contentSong item">
<div class="title"><div class="inner"><h1 class="fn">Paroles de la chanson «Amsterdam» (avec traduction) par Jacques Brel</h1>
</div></div>
<div class="digbury" style="float:left"><div class="inner"><a href="#" class="contentDig" onclick="dwUser.exec(dwAjax.messages['contentDigBury'].signin, function(){dwContent.digbury('275679','contentDigBury-4762x275679');}); return false;"><img src="/spacer.gif?1410808470" alt=""/><span id="contentDigBury-4762x275679Dig">1</span></a> <a href="#" class="contentBury" onclick="dwUser.exec(dwAjax.messages['contentDigBury'].signin, function(){dwContent.digbury('275679','contentDigBury-4762x275679',true);}); return false;"><img src="/spacer.gif?1410808470" alt=""/><span id="contentDigBury-4762x275679Bury">0</span></a>
<span id="contentDigBury-4762x275679-message" style="display:none;"></span></div></div>
<div class="favorite" style="float:left"><div class="inner"><a href="#" onclick="dwUser.exec('', function(){dwAjax.postUpdate(dwService.getUrl('t', 'contents.favorite', 'id=275679'), 'favoriteForm-4762')}); return false;" onmouseover="dwTooltip.show(this, 'Ajouter/supprimer «Amsterdam» de mes contenus favoris');" onmouseout="dwTooltip.hide(this);"><img src="/iconfavorites.png?1410808470" alt=""/></a>
<span id="favoriteForm-4762-message" style="display:none"></span>
<script type="text/javascript"><!--
dwAjax.setMessages('favoriteForm-4762', {0:'«Amsterdam» a été ajouté à vos contenus favoris', 1:'veuillez vous connecter', 3:'«Amsterdam» a été supprimé de vos contenus favoris'});//-->
</script></div></div>
<div class="like" style="float:left"><div class="inner">
<table class="likeWidget">
<tr>
<td>
<div style="width:108px;height:20px;" id="share-like-box-0">
<script type="text/javascript"><!--
dwElement.addEvent(null, 'load', function ()
{
dwElement.setValue('share-like-box-0', '<iframe width="108" height="20" src="http://www.facebook.com/plugins/like.php?extended_social_context=false&amp;font=verdana&amp;href=' + encodeURIComponent(document.location.href.replace(/(\/[0-9]+\.)[a-zA-Z0-9]+\.html/, '$1html')) + '&amp;layout=button_count&amp;locale=fr_FR&send=false&amp;show_faces=false" frameborder="0" scrolling="no" vspace="0" hspace="0" marginheight="0" marginwidth="0"></iframe>');
});//-->
</script>
</div>
</td>
<td>
<div style="width:110px;height:20px;" id="share-like-box-1">
<script type="text/javascript"><!--
dwElement.addEvent(null, 'load', function ()
{
dwElement.setValue('share-like-box-1', '<iframe width="110" height="20" src="http://platform.twitter.com/widgets/tweet_button.html#count=horizontal&lang=fr&url=' + encodeURIComponent(document.location.href.replace(/(\/[0-9]+\.)[a-zA-Z0-9]+\.html/, '$1html')) + '&text=' + encodeURIComponent(document.title) + '" frameborder="0" scrolling="no" vspace="0" hspace="0" marginheight="0" marginwidth="0"></iframe>');
});//-->
</script>
</div>
</td>
<td>
<div style="width:81px;height:20px;" id="share-like-box-2">
<script type="text/javascript"><!--
dwElement.addEvent(null, 'load', function ()
{
dwElement.setValue('share-like-box-2', '<iframe width="81" height="20" src="https://apis.google.com/u/0/_/+1/fastbutton?url=' + encodeURIComponent(document.location.href.replace(/(\/[0-9]+\.)[a-zA-Z0-9]+\.html/, '$1html')) + '&amp;size=medium&amp;annotation=bubble&amp;hl=fr" frameborder="0" scrolling="no" vspace="0" hspace="0" marginheight="0" marginwidth="0"></iframe>');
});//-->
</script>
</div>
</td>
</tr>
</table>
</div></div>
<div class="media" style="clear:left;float:left"><div class="inner">
<a href="/216466.html" title="Jacques Brel"><img src="/593869-2544.jpg?20120608" width="110" height="110" style="margin:0px 0px;" alt="Live Olympia 1964 (1964)"/></a></div></div>
<div class="album"><div class="inner"><strong>Albums :</strong>
<a href="/233206.html">Live Olympia 1964</a></div></div>
<div class="tonefuse"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://www.ringtonematcher.com/co/ringtonematcher/02/noc.php?sid=LCCLros&amp;artist=jacques+brel&amp;song=amsterdam'); return false"><img src="/tonefuseleft.png?1410808470" alt=""/> <span>Télécharge la sonnerie de "Amsterdam" pour ton mobile</span></a></div></div>
<div class="itunes" style="float:left"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://clk.tradedoubler.com/click?p=23753&amp;a=1284621&amp;url=http%3A%2F%2Fphobos.apple.com%2FWebObjects%2FMZSearch.woa%2Fwa%2Fsearch%3Fterm=jacques%20brel%20amsterdam%26partnerId%3D2003'); return false;" title="Acheter l'album ou les MP3 sur iTunes"><img src="/itunes.png?1410808470" alt="Acheter l'album ou les MP3 sur iTunes"/></a></div></div>
<div class="viagogo" style="float:left"><div class="inner">
<a href="#" onclick="dwDocument.openWindow('http://www.viagogo.fr/search?q=jacques%20brel&amp;AffiliateID=1579&amp;PCID=AFFFRIAFF15791579F0459F97D1'); return false;" title="Acheter des places de concert sur Viagogo"><img src="/viagogo.png?1410808470" alt="Acheter des places de concert sur Amazon"/></a></div></div>
<div class="amazon" style="float:left"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://www.amazon.fr/exec/obidos/ASIN/B0000AKOLB/lacoccindunet-21'); return false;" title="Acheter l'album ou les MP3 sur Amazon"><img src="/amazon.png?1410808470" alt="Acheter l'album ou les MP3 sur Amazon"/></a>
</div></div>
<div class="fnac" style="float:left"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://ad.zanox.com/ppc/?8735413C1813773704T&amp;ULP=[[musique.fnac.com%2F1582578%2F]]'); return false;" title="Acheter l'album ou les MP3 sur Fnac"><img src="/fnac.png?1410808470" alt="Acheter l'album ou les MP3 sur Fnac"/></a>
</div></div>
<div class="persons" style="clear:left;"><div class="inner empty"></div></div>
<div class="jukebo"><div class="inner"><table width="100%">
<tr>
<td><span>Voir tous les clips</span> <a href="#" title="jukebo" onclick="dwDocument.openWindow('http://www.jukebo.fr/jacques-brel'); return false;">Jacques Brel</a></td>
<td>
<div id="disableJukebo" style="display:none"><a href="#" onclick="dwUtils.createCookie('dwJukebo', '1', 30, '/'); dwElement.setValue('disableJukebo', 'Désactivation effectuée pour les 30 prochains jours'); return false;">Désactiver la lecture automatique des vidéos</a></div>
</td>
</tr>
</table>
<script type="text/javascript"><!--
var ULTIMEDIA_zone = '1', c = dwUtils.readCookie('dwJukebo');
// S'il y a le cookie sans autoplay, on utilise la zone 3
if (c && c === '1') {
ULTIMEDIA_zone = '3';
}
if (ULTIMEDIA_zone === '1') {
dwElement.setDisplayStyle('disableJukebo');
}
//-->
</script>
<div id="jukebo-iframe" style="width:605px;height:340px;background-color:#f4f4f4"></div><script type="text/javascript"><!--
dwElement.addEvent(null, 'load', function ()
{
var iframe = document.createElement('iframe');
iframe.style.border = '0';
iframe.scrolling = 'no';
iframe.width = 605;
iframe.height = 340;
iframe.src = 'http://www.ultimedia.com/deliver/musique/iframe/mdtk/01497444/article/3ulx3/width/605/height/340/zone/' + ULTIMEDIA_zone + '/';
dwElement.get('jukebo-iframe').appendChild(iframe);
});//--></script>
</div></div>
<div class="text"><div class="inner"><h3>Paroles et traduction de «Amsterdam»</h3>
<p>Amsterdam ()<br class="clear" style="clear:both;"/></p><p>Dans le port d'Amsterdam<br/>Y a des marins qui chantent<br/>Les rêves qui les hantent<br/>Au large d'Amsterdam<br/>Dans le port d'Amsterdam<br/>Y a des marins qui dorment<br/>Comme des oriflammes<br/>Le long des berges mornes<br/>Dans le port d'Amsterdam<br/>Y a des marins qui meurent<br/>Pleins de bière et de drames<br/>Aux premières lueurs<br/>Mais dans le port d'Amsterdam<br/>Y a des marins qui naissent<br/>Dans la chaleur épaisse<br/>Des langueurs océanes<br/>Dans le port d'Amsterdam<br/>Y a des marins qui mangent<br/>Sur des nappes trop blanches<br/>Des poissons ruisselants<br/>Ils vous montrent des dents<br/>A croquer la fortune<br/>A décroisser la lune<br/>A bouffer des haubans<br/>Et ça sent la morue<br/>Jusque dans le coeur des frites<br/>Que leurs grosses mains invitent<br/>A revenir en plus<br/>Puis se lèvent en riant<br/>Dans un bruit de tempête<br/>Referment leur braguette<br/>Et sortent en rotant<br/>Dans le port d'Amsterdam<br/>Y a des marins qui dansent<br/>En se frottant la panse<br/>Sur la panse des femmes<br/>Et ils tournent et ils dansent<br/>Comme des soleils crachés<br/>Dans le son déchiré<br/>D'un accordéon rance<br/>Ils se tordent le cou<br/>Pour mieux s'entendre rire<br/>Jusqu'à ce que tout à coup<br/>L'accordéon expire<br/>Alors le geste grave<br/>Alors le regard fier<br/>Ils ramènent leur batave<br/>Jusqu'en pleine lumière<br/>Dans le port d'Amsterdam<br/>Y a des marins qui boivent<br/>Et qui boivent et reboivent<br/>Et qui reboivent encore<br/>Ils boivent à la santé<br/>Des putains d'Amsterdam<br/>De Hambourg ou d'ailleurs<br/>Enfin ils boivent aux dames<br/>Qui leur donnent leur joli corps<br/>Qui leur donnent leur vertu<br/>Pour une pièce en or<br/>Et quand ils ont bien bu<br/>Se plantent le nez au ciel<br/>Se mouchent dans les étoiles<br/>Et ils pissent comme je pleure<br/>Sur les femmes infidèles<br/>Dans le port d'Amsterdam<br class="clear" style="clear:both;"/></p><p></p>
<div style="clear:both;" class="clr-zone">&nbsp;</div>
</div></div>
<div class="tonefuse"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://www.ringtonematcher.com/co/ringtonematcher/02/noc.php?sid=LCCLros&amp;artist=jacques+brel&amp;song=amsterdam'); return false"><img src="/tonefuseleft.png?1410808470" alt=""/> <span>Télécharge la sonnerie de "Amsterdam" pour ton mobile</span></a></div></div>
<div class="member"><div class="inner">Publié par <span class="reviewer"><span class="vcard"><a class="url fn" rel="author" href="/m/88876.html">Mourroun</a></span></span>, le 14 juillet 2006, 19:13 (<img src="/iconmail.png?1410808470" alt="" style="vertical-align:middle"/> <a href="#" onclick="dwUser.exec('Contacter', function(){dwUser.go('follow', 'dV9jfHVfaXxpfDI3NTY3OXw4ODg3Nnxt');}); return false;">Contacter</a>)
</div></div>
<div class="tags"><div class="inner empty"></div></div>
</div></div><!--/CoSo@4762--></div><div class="footer"></div></div>
<div id="clr-z3" class="clr-zone">&nbsp;</div>
<div id="zone3"><div class="header"></div><div id="subzone3"><!--LiCoRe@5588--><div class="similarSongs" id="block5588"><div class="list">
<h4 class="label">Chansons similaires</h4>
<div class="contents">
<p>
<span class="title">
<a href="/282953.html">Ne Me Quitte Pas</a></span><span class="artist"><a href="/216466.html">Jacques Brel</a></span>
</p>
<p>
<span class="title">
<a href="/289044.html">Le Plat Pays</a></span><span class="artist"><a href="/216466.html">Jacques Brel</a></span>
</p>
<p>
<span class="title">
<a href="/276293.html">La Valse à Mille Temps</a></span><span class="artist"><a href="/216466.html">Jacques Brel</a></span>
</p>
<p>
<span class="title">
<a href="/909041.html">Chandelier</a></span><span class="artist"><a href="/214142.html">Sia</a></span>
</p>
<p>
<span class="title">
<a href="/785400.html">Quand on n'a que l'amour</a></span><span class="artist"><a href="/216466.html">Jacques Brel</a></span>
</p>
</div>
</div>
</div><!--/LiCoRe@5588--></div><div class="footer"></div></div>
<div id="clr-z4" class="clr-zone">&nbsp;</div>
<div id="zone4"><div class="header"></div><div id="subzone4"><!--AdDFP@7219--><div class="pub300"><script type="text/javascript"><!--
dwService.dfpFillSlot("7219-336x280",336,280); //-->
</script><!-- dfp@0 --></div><!--/AdDFP@7219--></div><div class="footer"></div></div>
<div id="clr-z5" class="clr-zone">&nbsp;</div>
<div id="zone5"><div class="header"></div><div id="subzone5"><!--Co@4764--><div class="comments">
<h3 class="label">Vos commentaires</h3>
<div id="contentComments">
<div>
</div>
<div class="commentsList">
<table cellpadding="2" cellspacing="0" width="100%">
<colgroup>
<col width="80px"/>
<col/>
</colgroup>
<tr id="cmt426316" class="odd">
<th class="author"><a href="/m/105300.html">Kurdt Kobain</a> </th>
<th class="date">
Il y a 7 an(s) 7 mois à 10:16
</th>
</tr>
<tr class="odd">
<th class="avatar"><a href="/m/105300.html" title="Kurdt Kobain"><img class="photo" src="http://www.lacoccinelle.net/0000-0.jpg?20120421" width="64" height="64" style="margin:13px 13px;" alt="Kurdt Kobain"/></a></th>
<td class="comment">J'adore... eh oui... Un mordu de Nirvana qui écoute du Brel ! Un lien existe néanmoins entre les deux! Non ?!? Si !!<br/>Nirvana a repris une chanson appelée &quot;Seasons in the sun&quot;, chantée à l'origine par Terry Jacks. Cette même chanson est issue d'une collaboration avec... le grand Jacques Brel.</td>
</tr>
<tr class="odd">
<td class="website"></td>
<td class="buttons">
<a href="#" onclick="dwUser.exec('Connectez-vous pour signaler un commentaire abusif', function(){dwContent.alert('Alerte',275679,'alertCmt-426316',426316);}); return false;" onmouseover="dwTooltip.show(this, 'Signaler un abus');" onmouseout="dwTooltip.hide(this);"><img src="/iconwarning.png?1410808470" alt=""/></a>
<p id="alertCmt-426316-message" style="display:none;"></p>
</td>
</tr>
<tr id="cmt442698" class="even">
<th class="author"><a href="/m/83541.html">Titouuu</a> </th>
<th class="date">
Il y a 7 an(s) 4 mois à 20:52
</th>
</tr>
<tr class="even">
<th class="avatar"><a href="/m/83541.html" title="Titouuu"><img class="photo" src="http://www.lacoccinelle.net/474902-0.jpg?20120608" width="90" height="90" style="margin:0px 0px;" alt="Titouuu"/></a></th>
<td class="comment">Impressionnante! L'une de mes préférées avec &quot;la valse à mille temps&quot; et .... &quot;Ne me quitte pas&quot;, evidemment.</td>
</tr>
<tr class="even">
<td class="website"><a href="http://amblin01.skyrock.com" onclick="window.open(this.href, 'website'); return false;" rel="external nofollow" onmouseover="dwTooltip.show(this, '&lt;strong&gt;Site web&lt;/strong&gt; http://amblin01.skyrock.com');" onmouseout="dwTooltip.hide(this);">Site web</a></td>
<td class="buttons">
<a href="#" onclick="dwUser.exec('Connectez-vous pour signaler un commentaire abusif', function(){dwContent.alert('Alerte',275679,'alertCmt-442698',442698);}); return false;" onmouseover="dwTooltip.show(this, 'Signaler un abus');" onmouseout="dwTooltip.hide(this);"><img src="/iconwarning.png?1410808470" alt=""/></a>
<p id="alertCmt-442698-message" style="display:none;"></p>
</td>
</tr>
<tr id="cmt493238" class="odd">
<th class="author"><a href="/m/116334.html">Poliineuh</a> </th>
<th class="date">
Il y a 6 an(s) 1 mois à 23:04
</th>
</tr>
<tr class="odd">
<th class="avatar"><a href="/m/116334.html" title="Poliineuh"><img class="photo" src="http://www.lacoccinelle.net/493021-0.jpg?20120608" width="90" height="70" style="margin:10px 0px;" alt="Poliineuh"/></a></th>
<td class="comment">Tres tres grand!!!</td>
</tr>
<tr class="odd">
<td class="website"></td>
<td class="buttons">
<a href="#" onclick="dwUser.exec('Connectez-vous pour signaler un commentaire abusif', function(){dwContent.alert('Alerte',275679,'alertCmt-493238',493238);}); return false;" onmouseover="dwTooltip.show(this, 'Signaler un abus');" onmouseout="dwTooltip.hide(this);"><img src="/iconwarning.png?1410808470" alt=""/></a>
<p id="alertCmt-493238-message" style="display:none;"></p>
</td>
</tr>
</table>
</div>
</div>
<form action="/transactions/comment.php" id="dwCmtForm" method="post" onsubmit="dwUser.exec('Connectez-vous pour ajouter un commentaire', dwContent.postComment); return false;">
<table id="dwCmtTable">
<colgroup>
<col width="80px"/>
<col/>
<col width="150px"/>
</colgroup>
<tr>
<td rowspan="2" id="dwCmtPseudo"><span id="dwCmtUserMsg_small2avatar_"></span></td>
<td colspan="2">
<input type="hidden" name="conId" id="cmtId" value="275679"/>
<input type="hidden" name="md5" id="cmtMd5" value="bf46ca599ce49eb1b54672db93c4af3c"/>
<textarea name="comment" id="dwCmtTxt" cols="50" rows="2" onfocus="if (this.value === 'Ajoutez votre commentaire...') this.value = '';" onkeyup="dwContent.updateCommentLength();">Ajoutez votre commentaire...</textarea>
</td>
</tr>
<tr>
<td style="text-align:left"><em>Caractères restants : <span id="dwCmtLength">1000</span></em></td>
<td style="text-align:right"><input class="submit" type="submit" value="Commenter"/></td>
</tr>
</table>
</form>
<div id="dwCmtForm-message" style="display:none"></div>
<script type="text/javascript"><!--
dwContent.cmtOwnerId = dwUtils.toInt('0');
dwUser.displayIfLogged('dwCmtLogged', 'dwCmtNotLogged1');
dwUser.displayIfLogged(false, 'dwCmtNotLogged3');
dwUser.displayIfLogged(false, 'dwCmtNotLogged4');
dwUser.displayIfLogged('dwCmtUserMsg_small2avatar_');
if (dwUser.isLogged === false)
{
dwElement.setValue('dwCmtUserName', dwUser.pseudo);
dwElement.setValue('dwCmtUserEmailConfirm', dwUser.mail);
dwElement.setValue('dwCmtUserWebsite', dwUser.website);
}
else
{
dwElement.setValue('dwCmtUserName', '');
dwElement.setValue('dwCmtUserEmailConfirm', '');
dwElement.setValue('dwCmtUserWebsite', '');
}
dwAjax.setMessages('dwCmtForm', {0:'Votre commentaire a été ajouté avec succès, il sera affiché dans quelques instants', 1:'Une erreur est survenue lors de l\'ajout de votre commentaire, veuillez nous excuser du désagrément', 2:'Votre commentaire a été ajouté avec succès, il sera affiché aprés modération', 3:'Votre commentaire est vide', 5:'Votre commentaire est trop long', 7:'Vous avez posté il y a quelques secondes un commentaire similaire, merci de patienter le temps qu\'il s\'affiche', 9:'Un champ obligatoire est vide', 11:'Adresse email non valide', 13:'URL du site internet non valide', 15:'Adresse email enregistrée <a href="#" onclick="dwUser.exec(\'Connectez-vous pour ajouter un commentaire\', dwContent.postComment);return false;">Connectez-vous</a>'});
dwAjax.setMessages('cmtDigBury', {0:'Merci de votre participation', 1:'Une erreur est survenue, vérifiez que vous êtes toujours connecté'});
dwAjax.setMessages('chooseCmt', {0:'Votre choix apparaîtra dans quelques instants', 1:'Une erreur est survenue, vérifiez que vous êtes toujours connecté'});
dwAjax.setMessages('alertCmt', {0:'Merci de votre participation'});
dwContent.loadComment(); //-->
</script></div><!--/Co@4764--></div><div class="footer"></div></div>
<div id="clr-zLast" class="clr-zone">&nbsp;</div>
</div>
</div>
<div id="body-footer"></div>
</div>
<div id="footer-background">
<div id="footer">
<div id="footer-content">
<div class="header"></div>
<!--Ht@4820--><div class="boxFooter">
<div id="htmlNotLogged-4820"><div class="titleFooter">À PROPOS</div>
<p>Depuis 2001, La Coccinelle propose et construit une communauté musicale.</p>
<br/><br/>
<p>Le site s'est développé autour d'une idée simple : comprendre les paroles des chansons françaises et internationales, qui souvent regorgent de nombreux secrets.</p>
<br/><br/>
<div class="starFooter"><a href="#" onclick="dwUser.login(); return false">Devenir membre de la communauté</a></div></div>
<div id="htmlLogged-4820"><div class="titleFooter">À PROPOS</div>
<p>Depuis 2001, La Coccinelle propose et construit une communauté musicale.</p>
<br/><br/>
<p>Le site s'est développé autour d'une idée simple : comprendre les paroles des chansons françaises et internationales, qui souvent regorgent de nombreux secrets.</p>
<br/><br/></div>
<script type="text/javascript"><!--
dwUser.displayIfLogged('htmlLogged-4820','htmlNotLogged-4820'); //-->
</script>
</div><!--/Ht@4820--><!--Ht@4821--><div class="boxFooter"><div class="titleFooter">TOP RUBRIQUES</div>
<ul>
<li><a href="/top/index.html">Top 50 chansons</a></li>
<li><a href="/dc/index.html">Derniers ajouts</a></li>
<li><a href="/liens/index.html">Partenaires</a></li>
<li><a href="/faq/index.html">Foire aux questions</a></li>
<li><a href="http://www.annonces.com" title="petite annonce">Annonce</a></li>
</ul>
<ul>
<li><a href="/actus/index.html">Actualités</a></li>
<li><a href="/index.html">Paroles de chansons</a></li>
<li><a href="#" onclick="dwUser.go('account'); return false;">Mon compte</a></li>
<li><a href="http://www.soonnight.com/mag/actualites/soiree-reveillon-jour-de-l-an-paris,28,2345.html">Nouvel an Paris</a></li>
</ul>
</div><!--/Ht@4821--><!--Ht@4822--><div class="boxFooter linkCocci"><div class="titleFooter">SUIVEZ LA COCCINELLE</div>
<div class="icoFollow"><a href="/actus/rss.xml">Les actus via RSS</a></div>
<div class="icoFollow twitterF"><a href="http://twitter.com/lacoccinellenet" onclick="dwDocument.openWindow(this.href, 'twitter');return false">Suivez-nous sur Twitter</a></div>
<div class="icoFollow facebookF"><a href="http://www.facebook.com/pages/La-Coccinelle-du-Net/140698937843" onclick="dwDocument.openWindow(this.href, 'facebook');return false">Rejoignez-nous sur facebook</a></div>
</div><!--/Ht@4822--><!--Ht@4816--><div class="copyright">&copy;2001-2014 LaCoccinelle.net
</div><!--/Ht@4816--><!--Ht@4817--><div class="menuFooter"><a href="/index.html">Accueil</a> <!--<a href="">A propos de la coccinelle</a>--> <a href="#" onclick="dwService.open('tou');return false">CGU</a> <a href="/s/index.html">Contact</a>
</div><!--/Ht@4817--><!--Ht@7031--><div class="hideTools"><script type="text/javascript" src="/seemore.js?1410808470"></script><script type="text/javascript" src="/tools.js?1410808470"></script>
</div><!--/Ht@7031-->
<div class="footer"></div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,522 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Paroles de Lilly Wood The Prick : Hey It's Ok - paroles de chanson</title>
<meta name="description" content="Lilly Wood The Prick : Hey It's Ok paroles de la chanson "/>
<link href="/s.css?1380773110" rel="stylesheet" type="text/css" title="default"/>
<script type="text/javascript" src="/g.js?1380773110"></script>
<script type="text/javascript"><!--
dwService.reload = false;
dwService.setTargetings({"pagId":"2508","pagType":"content","layId":"551","directories":["\/paroles-officielles\/","\/"],"conId":"550512","appId":"5873"});
initGA(['UA-4587199-1', 'UA-26394066-3']);
initWAI('dugwood', 474759, 474760);//-->
</script>
<link rel="icon" type="image/gif" href="/favicon.gif?1380773110"/>
<script type="text/javascript"><!--
var cocci_sas_target = 'noft';
if (document.location.pathname === '/index.html')
{
cocci_sas_target = 'home';
}
var disableExpand = {2013918: 'sfr-red-tstm', 2013921: 'sfr-red-nuitsfr'},
date = new Date(),
cocci_sas_sfr = '';
if (disableExpand['' + date.getFullYear() + (date.getMonth() + 1) + date.getDate()] || document.location.hash.indexOf('#sfr-red-') === 0)
{
cocci_sas_sfr = disableExpand['' + date.getFullYear() + (date.getMonth() + 1) + date.getDate()] || document.location.hash.substring(1);
}//-->
</script>
</head>
<body id="layout551" class="dom1 contentPage cdirParolesOfficielles app5873 status3">
<div id="contener">
<div id="header-background">
<div id="header">
<div id="header-content">
<div class="header"></div>
<!--Ht@7076--><div class="headerLogo"><a href="/index.html"><img src="/logo-2013.png?1380773110" width="200" height="64" alt="Accueil paroles de chansons"/></a>
</div><!--/Ht@7076--><!--LoBo@4755--><div class="zoneLogin"><div id="loginBoxLogged" style="display:none" class="loginBox">
<div class="pseudo" style="float:left">
<a href="#" title="Mon compte" onclick="dwUser.go('account');return false;" id="loginBox_pseudo_">&nbsp;</a><script type="text/javascript"><!--
dwUser.displayIfLogged('loginBox_pseudo_');//-->
</script>
</div>
<div class="mypage" style="float:left">
<a href="#" title="Ma page personnelle" onclick="dwUser.go('user');return false;" class="button">&nbsp;</a>
</div>
<div class="admin" style="float:left">
<a href="#" title="Mes contenus" class="button" onclick="dwUser.go(); return false;">&nbsp;</a>
</div>
<div class="addcontent" style="float:left">
<a href="#" onclick="dwUser.go('content');return false;" title="Ajouter un contenu" class="button">&nbsp;</a>
</div>
<div class="editcontent" style="float:left">
<a href="#" title="Éditer ce contenu" class="button" style="display:none" id="loginBox_editcontent_">&nbsp;</a>
<script type="text/javascript"><!--
var m = document.location.href.match(/\/(\d+)\.html/);
if (m && m[1] && document.location.href.indexOf('/m/') === -1)
{
dwElement.setDisplayStyle('loginBox_editcontent_', true);
dwElement.get('loginBox_editcontent_').onclick = function ()
{
dwUser.go('content', m[1]);return false;
}
} //-->
</script>
</div>
<div class="messages" style="float:left">
<a href="#" onclick="dwUser.go('message');return false;" title="Mes messages" class="button"><span id="loginBox_msg_" class="number">&nbsp;</span></a><script type="text/javascript"><!--
dwUser.displayIfLogged('loginBox_msg_');//-->
</script>
</div>
<div class="notifications" style="float:left">
<a href="#" onclick="dwUser.go('notifications');return false;" title="Notifications" class="button"><span id="loginBox_notif_" class="number">&nbsp;</span></a><script type="text/javascript"><!--
dwUser.displayIfLogged('loginBox_notif_');//-->
</script>
</div>
<div class="friends" style="float:left">
<a href="#" onclick="dwUser.go('friends');return false;" title="Amis" class="button"><span id="loginBox_fr_" class="number">&nbsp;</span></a><script type="text/javascript"><!--
dwUser.displayIfLogged('loginBox_fr_');//-->
</script>
</div>
<div class="favorites" style="float:left">
<a href="#" onclick="dwLightBox.cache = true; dwLightBox.open('Mes contenus favoris', dwService.getUrl('s', 'contents.favorites'), 'ajax');return false;" title="Contenus favoris" class="button">&nbsp;</a>
</div>
<div class="logout" style="float:left">
<a href="#" title="Déconnexion" onclick="dwUser.logout(); return false;" class="button">&nbsp;</a>
</div>
<div class="clr-zone" style="clear:left">&nbsp;</div>
</div>
<div id="loginBoxNotLogged" class="loginBox">
<a href="#" title="Connexion" onclick="dwUser.login();return false;">Connexion</a> - <a href="#" title="Inscription" onclick="dwService.open('register', 'Inscription');return false;">Inscription</a>
</div>
<script type="text/javascript"><!--
dwUser.displayIfLogged('loginBoxLogged','loginBoxNotLogged'); //-->
</script></div><!--/LoBo@4755--><!--Ht@7075--><div class="headerMenu"><table cellpadding="0" cellspacing="0">
<tr>
<td><a href="/index.html">CHANSONS</a></td>
<td><a href="/artistes/index.html">ARTISTES</a></td>
<td><a href="/albums/index.html">ALBUMS</a></td>
<td><a href="/paroles-officielles/index.html">PAROLES OFFICIELLES</a></td>
</tr>
</table>
</div><!--/Ht@7075--><!--Ht@7077--><div class="headerTitle"><img src="/home-title.png?1380773110" width="693" height="110" alt="Paroles de chansons, traductions, explications"/>
</div><!--/Ht@7077--><!--SeFo@7074--><div class="headerSearch">
<form action="/s.html" method="post" id="searchForm-7074" onsubmit="return dwSearch.send(this.id);">
<p><span class="searchForm"><input type="text" name="q" id="searchForm-7074-q" size="15" alt="Rechercher une chanson, un artiste..." value="Rechercher une chanson, un artiste..." onfocus="if(typeof(dwSearch.d['searchForm-7074']) === 'undefined' || dwSearch.d['searchForm-7074'] === this.value) this.value = ''"/><a href="#" onclick="if (dwSearch.send('searchForm-7074') === true) dwElement.get('searchForm-7074').submit(); return false;"><img id="searchForm-7074-default" src="/spacer.gif?1380773110" alt="Rechercher une chanson, un artiste..."/></a></span><input type="submit" style="display:none"/><!-- affiché uniquement pour qu'en tapant sur entrée dans un champ ça POST le formulaire --></p>
<p id="searchForm-7074-message" style="display: none">&nbsp;</p>
</form>
<script type="text/javascript"><!--
dwAjax.setMessages('searchForm-7074', {1:'Veuillez entrer au moins un mot-clé de recherche'});
dwSearch.restore('searchForm-7074');//-->
</script></div><!--/SeFo@7074--><!--Ht@4808--><div class="pub728"><script type="text/javascript"><!--
SmartAdServerAjax('2301/16363',438,cocci_sas_target,'ww62.smartadserver.com');//-->
</script>
</div><!--/Ht@4808-->
<div class="footer"></div>
</div>
</div>
</div>
<div id="body-background">
<div id="body-header"></div>
<div id="body">
<div id="body-content">
<div id="zone1"><div class="header"></div><div id="subzone1"><!--PaFi@6710--><div class="breadcrumb">
<div id="breadcrumb" class="dwBreadcrumb"><a href="/index.html" title="Accueil">Accueil</a> &gt; <a href="/paroles-officielles/index.html" title="Paroles de chansons officielles">Paroles de chansons officielles</a> &gt; <a href="/paroles-officielles/830989.html" title="Lilly Wood The Prick">Lilly Wood The Prick</a> </div></div><!--/PaFi@6710--><!--CoSo@5873--><div><div id="content550512" class="content contentSong item">
<div class="title"><div class="inner"><h1 class="fn">Hey It's Ok - Lilly Wood The Prick</h1>
</div></div>
<div class="itunes" style="clear:right;float:right"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://clk.tradedoubler.com/click?p=23753&amp;a=1284621&amp;url=http%3A%2F%2Fphobos.apple.com%2FWebObjects%2FMZSearch.woa%2Fwa%2Fsearch%3Fterm=lilly%20wood%20the%20prick%20hey%20it%20s%20ok%26partnerId%3D2003'); return false;" title="Acheter l'album ou les MP3 sur iTunes"><img src="/itunes.png?1380773110" alt="Acheter l'album ou les MP3 sur iTunes"/></a></div></div>
<div class="amazon" style="float:right"><div class="inner">
<a href="#" onclick="dwDocument.openWindow('http://www.amazon.fr/gp/search?ie=UTF8&amp;index=mp3-downloads&amp;keywords=lilly%20wood%20the%20prick%20hey%20it%20s%20ok&amp;tag=lacoccindunet-21'); return false;" title="Acheter l'album ou les MP3 sur Amazon"><img src="/amazon.png?1380773110" alt="Acheter l'album ou les MP3 sur Amazon"/></a></div></div>
<div class="fnac" style="float:right"><div class="inner">
<a href="#" onclick="dwDocument.openWindow('http://ad.zanox.com/ppc/?8735413C1813773704T&amp;ULP=[[recherche.fnac.com%2FSearch%2FSearchResult.aspx%3FSCat=3%211&amp;Search=lilly%20wood%20the%20prick]]'); return false;" title="Acheter l'album ou les MP3 sur Fnac"><img src="/fnac.png?1380773110" alt="Acheter l'album ou les MP3 sur Fnac"/></a>
</div></div>
<div class="album" style="clear:right;"><div class="inner empty"><strong>Albums :</strong>
</div></div>
<div class="persons"><div class="inner">
<strong>Chanteurs :</strong>
<a href="/paroles-officielles/830989.html">Lilly Wood The Prick</a><br/>
<strong>Compositeurs :</strong>
<a href="/paroles-officielles/830987.html">Benjamin Cotto</a>, <a href="/paroles-officielles/830967.html">Nili Ben Meir</a><br/>
<strong>Auteurs :</strong>
<a href="/paroles-officielles/830987.html">Benjamin Cotto</a>, <a href="/paroles-officielles/830967.html">Nili Ben Meir</a><br/>
<strong>Arrangeurs :</strong>
<a href="/paroles-officielles/830934.html">Pierre Guimard</a><br/>
<strong>Éditeurs :</strong>
<a href="/paroles-officielles/545774.html">Choke Industry</a>, <a href="/paroles-officielles/545654.html">Warner Chappell Music France</a><br/>
</div></div>
<div class="tonefuse"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://www.ringtonematcher.com/co/ringtonematcher/02/noc.php?sid=LCCLros&amp;artist=lilly+wood+the+prick&amp;song=hey+it+s+ok'); return false"><img src="/tonefuseLeft.png?1380773110" alt=""/> <span>Télécharge la sonnerie de "Hey It's Ok" pour ton mobile</span></a></div></div>
<div class="jukebo"><div class="inner"><table width="100%">
<tr>
<td><span>Voir tous les clips</span> <a href="#" title="jukebo" onclick="window.open('http://www.jukebo.fr/lilly-wood-and-the-prick', 'jukebo'); return false;">Lilly Wood And The Prick</a></td>
<td>
<div id="disableJukebo" style="display:none"><a href="#" onclick="dwUtils.createCookie('dwJukebo', '1', 30, '/'); dwElement.setValue('disableJukebo', 'Désactivation effectuée pour les 30 prochains jours'); return false;">Désactiver la lecture automatique des vidéos</a></div>
</td>
</tr>
</table>
<script type="text/javascript"><!--
var ULTIMEDIA_zone = '1', c = dwUtils.readCookie('dwJukebo');
// S'il y a le cookie sans autoplay, on utilise la zone 3
if (c && c === '1') {
ULTIMEDIA_zone = '3';
}
if (ULTIMEDIA_zone === '1') {
dwElement.setDisplayStyle('disableJukebo');
}
//-->
</script>
<script type='text/javascript'><!--
var ULTIMEDIA_include = '<scr' + 'ipt type="text/javascript" src="http://www.ultimedia.com/deliver/musique/js/mdtk/01497444/article/qksfuz/zone/' + ULTIMEDIA_zone + '/"></scr' + 'ipt>';document.write(ULTIMEDIA_include);
//--></script>
</div></div>
<div class="text"><div class="inner"><h3>Paroles de la chanson &quot;Hey It's Ok&quot;</h3>
<p>Mama, Papa please forget the times I wet my bed<br/>I swear not to do it again<br/>Please forget the way I looked when I was fourteen<br/>I didnt know who I wanted to be<br class="clear" style="clear:both;"/></p><p>Hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br/>I said hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br class="clear" style="clear:both;"/></p><p>Friends and lovers please forgive the mean things Ive said<br/>I swear not to do it again<br/>Please forget the way I act when Ive had too much to drink<br/>Im fighting against myself<br class="clear" style="clear:both;"/></p><p>Hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br/>I said hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br class="clear" style="clear:both;"/></p><p>And I swear not to do anything funny anymore<br/>Yes I swear not to do anything funny anymore<br class="clear" style="clear:both;"/></p><p>Hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br/>I said hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br class="clear" style="clear:both;"/></p><p>Hey ! Its OK, its OK<br/>Cause Ive found what I wanted<br/>I said hey ! Its OK, its OK<br/>Cause Ive found what I wanted</p>
<div style="clear:both;" class="clr-zone">&nbsp;</div>
</div></div>
<div class="tonefuse"><div class="inner"><a href="#" onclick="dwDocument.openWindow('http://www.ringtonematcher.com/co/ringtonematcher/02/noc.php?sid=LCCLros&amp;artist=lilly+wood+the+prick&amp;song=hey+it+s+ok'); return false"><img src="/tonefuseLeft.png?1380773110" alt=""/> <span>Télécharge la sonnerie de "Hey It's Ok" pour ton mobile</span></a></div></div>
</div></div><!--/CoSo@5873--><!--AdDFP@6768--><div class="pub300"><script type="text/javascript"><!--
dwService.dfpFillSlot("6768-300x250",300,250); //-->
</script><!-- dfp@0 --></div><!--/AdDFP@6768--></div><div class="footer"></div></div>
<div id="clr-z1" class="clr-zone">&nbsp;</div>
<div id="zone2"><div class="header"></div><div id="subzone2"><!--Ht@4807--><div class="pub300"><script type="text/javascript"><!--
SmartAdServerAjax('2301/16363',439,cocci_sas_target,'ww62.smartadserver.com');//-->
</script>
</div><!--/Ht@4807--><!--Ht@4840--><div class="box facebox"><h4>Facebook / Soirées</h4>
<div id="facebookIframe"></div><div id="soonnightIframe"></div>
<script type="text/javascript"><!--
dwElement.addEvent(null, 'load', function()
{
dwElement.setValue('facebookIframe', '<i' + 'frame src="http://www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Flacoccinelle.net&amp;width=288&amp;colorscheme=light&amp;show_faces=false&amp;stream=false&amp;header=false&amp;height=70" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:288px; height:70px;" allowTransparency="true"></i' + 'frame>');
// SoonNight
dwElement.setValue('soonnightIframe', '<i' + 'frame src="http://www.soonnight.com/agenda/agenda,1039.html?r=1&amp;url_page=http://www.soonnight.com&amp;color=white&amp;go_soonnight=1" width="268" height="142" scrolling="no" frameborder="0"></ifr' + 'ame>');
}); //-->
</script>
</div><!--/Ht@4840--></div><div class="footer"></div></div>
<div id="clr-z2" class="clr-zone">&nbsp;</div>
</div>
</div>
<div id="body-footer"></div>
</div>
<div id="footer-background">
<div id="footer">
<div id="footer-content">
<div class="header"></div>
<!--Ht@4820--><div class="boxFooter">
<div id="htmlNotLogged-4820"><div class="titleFooter">À PROPOS</div>
<p>Depuis 2001, La Coccinelle propose et construit une communauté musicale.</p>
<br/><br/>
<p>Le site s'est développé autour d'une idée simple : comprendre les paroles des chansons françaises et internationales, qui souvent regorgent de nombreux secrets.</p>
<br/><br/>
<div class="starFooter"><a href="#" onclick="dwUser.login(); return false">Devenir membre de la communauté</a></div></div>
<div id="htmlLogged-4820"><div class="titleFooter">À PROPOS</div>
<p>Depuis 2001, La Coccinelle propose et construit une communauté musicale.</p>
<br/><br/>
<p>Le site s'est développé autour d'une idée simple : comprendre les paroles des chansons françaises et internationales, qui souvent regorgent de nombreux secrets.</p>
<br/><br/></div>
<script type="text/javascript"><!--
dwUser.displayIfLogged('htmlLogged-4820','htmlNotLogged-4820'); //-->
</script>
</div><!--/Ht@4820--><!--Ht@4821--><div class="boxFooter">
<div id="htmlNotLogged-4821"><div class="titleFooter">TOP RUBRIQUES</div>
<ul>
<li><a href="/top/index.html">Top 50 chansons</a></li>
<li><a href="/dc/index.html">Derniers ajouts</a></li>
<li><a href="/liens/index.html">Partenaires</a></li>
<li><a href="/faq/index.html">Foire aux questions</a></li>
<li><a href="http://www.annonces.com" title="petite annonce">Annonce</a></li>
</ul>
<ul>
<li><a href="/actus/index.html">Actualités</a></li>
<li><a href="/index.html">Paroles de chansons</a></li>
<li><a href="#" onclick="dwUser.login(); return false;">Inscription</a></li>
</ul>
</div>
<div id="htmlLogged-4821"><div class="titleFooter">TOP RUBRIQUES</div>
<ul>
<li><a href="/top/index.html">Top 50 chansons</a></li>
<li><a href="/dc/index.html">Derniers ajouts</a></li>
<li><a href="/liens/index.html">Partenaires</a></li>
<li><a href="/faq/index.html">Foire aux questions</a></li>
<li><a href="http://www.annonces.com" title="petite annonce">Annonce</a></li>
</ul>
<ul>
<li><a href="/actus/index.html">Actualités</a></li>
<li><a href="/index.html">Paroles de chansons</a></li>
<li><a href="#" onclick="dwUser.go('account'); return false;">Mon compte</a></li>
</ul></div>
<script type="text/javascript"><!--
dwUser.displayIfLogged('htmlLogged-4821','htmlNotLogged-4821'); //-->
</script>
</div><!--/Ht@4821--><!--Ht@4822--><div class="boxFooter linkCocci"><div class="titleFooter">SUIVEZ LA COCCINELLE</div>
<div class="icoFollow"><a href="/actus/rss.xml">Les actus via RSS</a></div>
<div class="icoFollow twitterF"><a href="http://twitter.com/lacoccinellenet" onclick="dwDocument.openWindow(this.href, 'twitter');return false">Suivez-nous sur Twitter</a></div>
<div class="icoFollow facebookF"><a href="http://www.facebook.com/pages/La-Coccinelle-du-Net/140698937843" onclick="dwDocument.openWindow(this.href, 'facebook');return false">Rejoignez-nous sur facebook</a></div>
</div><!--/Ht@4822--><!--Ht@4816--><div class="copyright">&copy;2001-2014 LaCoccinelle.net
<script type="text/javascript"><!--
/* GestionPub Habillage temporaire */
if (cocci_sas_target !== 'curly' && !cocci_sas_sfr)
{
document.write('<sc' + 'ript type="text/javascript" src="http://a01.gestionpub.com/GP2a52c58652a78c759"></scr' + 'ipt>');
document.write('<sc' + 'ript type="text/javascript" src="http://a01.gestionpub.com/GP4221c74529ce2c"></scr' + 'ipt>');
}
dwElement.addEvent(null, 'load', function()
{
var s = document.createElement('script'),
node = document.getElementsByTagName('script')[0],
online = new Image(), members = new Image(), xiti = new Image();
/* GestionPub Footer Expand DESACTIVE * /
if (cocci_sas_target !== 'curly')
{
s.async = true;
s.type = 'text/javascript';
s.src = 'http://a01.gestionpub.com/GP2a72c88df2355ac48'; // Footer Expand
node.parentNode.insertBefore(s, node);
}
/* Connectés */
online.src = 'http://coccinelledunet.free.fr/online.png.php?host=lc';
if (dwUser.isLogged === true)
{
members.src = 'http://coccinelledunet.free.fr/online.png.php?host=lcm';
}
Xt_param = 's=175975&p=';
try {Xt_r = top.document.referrer;}
catch(e) {Xt_r = document.referrer; }
Xt_h = new Date();
Xt_i = 'http://logv26.xiti.com/hit.xiti?'+Xt_param;
Xt_i += '&hl='+Xt_h.getHours()+'x'+Xt_h.getMinutes()+'x'+Xt_h.getSeconds();
if(parseFloat(navigator.appVersion)>=4) {Xt_s=screen;Xt_i+='&r='+Xt_s.width+'x'+Xt_s.height+'x'+Xt_s.pixelDepth+'x'+Xt_s.colorDepth;}
xiti.src = Xt_i+'&ref='+Xt_r.replace(/[<>"]/g, '').replace(/&/g, '$');
});//-->
</script>
</div><!--/Ht@4816--><!--Ht@4817--><div class="menuFooter"><a href="/index.html">Accueil</a> <!--<a href="">A propos de la coccinelle</a>--> <a href="#" onclick="dwService.open('tou');return false">CGU</a> <a href="/s/index.html">Contact</a>
</div><!--/Ht@4817--><!--Ht@7031--><div class=""><script type="text/javascript"><!--
if (cocci_sas_sfr && cocci_sas_sfr === 'sfr-red-nuitsfr')
{
var sfrRed = {click:'http://ww62.smartadserver.com/call/cliccommand/8932016/[timestamp]?', image:'nuitsfr2', pixels:[]};
}
if (cocci_sas_sfr && cocci_sas_sfr.indexOf('sfr-red-') === 0)
{
dwElement.addEvent(null, 'load', function ()
{
if (document.location.href.indexOf('index.html') !== -1)
{
dwElement.get('sas_438').id = 'sas_438_disabled';
dwElement.get('sas_438_disabled').style.display = 'none';
}
for (var i in sfrRed.pixels)
{
var img = document.createElement('img');
img.src = sfrRed.pixels[i];
dwElement.get('footer-content').appendChild(img);
}
dwElement.get('contener').style.background = 'url(/pub-sfr-' + sfrRed.image + '.jpg) top center no-repeat';
dwElement.get('header').style.paddingTop = '200px';
document.body.style.background = '#000';
document.body.style.cursor = 'pointer';
dwElement.get('header-content').style.cursor = 'default';
dwElement.get('footer-content').style.cursor = 'default';
dwElement.get('body-content').style.cursor = 'default';
dwElement.get('footer-content').style.background = '#000';
dwElement.get('footer-background').style.background = 'none';
dwElement.addEvent(document.body, 'click', function(event)
{
if (event.target && event.target.id)
{
if (event.target.id === 'header' || event.target.id === 'footer' || event.target.id === 'body' || event.target.id === 'header-background' || event.target.id === 'footer-background' || event.target.id === 'body-background')
{
dwDocument.openWindow(sfrRed.click);
}
}
});
});
}
//-->
</script>
</div><!--/Ht@7031-->
<div class="footer"></div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -1,155 +1,154 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!doctype html>
<!--[if lt IE 7]> <html class="ie6 oldie"> <![endif]-->
<!--[if IE 7]> <html class="ie7 oldie"> <![endif]-->
<!--[if IE 8]> <html class="ie8 oldie"> <![endif]-->
<!--[if gt IE 8]><!-->
<html>
<!--<![endif]-->
<head>
<title>The Beatles - Lady Madonna Lyrics</title>
<meta http-equiv=content-language content=en-us>
<meta name="robots" content="INDEX,FOLLOW" >
<meta property="fb:admins" content="100002318964661" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="content-language" content="en-us">
<meta name="keywords" content="Lady Madonna, The Beatles, The Beatles Lady Madonna Lyrics, Lady Madonna song lyrics, Lady Madonna lyrics">
<meta name="description" content="Read guaranteed accurate human-edited The Beatles Lady Madonna lyrics from lyrics007">
<link rel="canonical" href="http://www.lyrics007.com/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html" />
<link rel="stylesheet" href="http://www.lyrics007.com/s.css" rev="stylesheet" type="text/css">
<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<script type="text/javascript" src="http://www.lyrics007.com/lyrics007.js"></script>
<script type="text/javascript" >
/* 007 - 728x90 - Top - Brand Ads only */
cf_page_artist = "The Beatles";
cf_page_song = "Lady Madonna";
</script>
<meta property="fb:admins" content="100002318964661" />
<title>The Beatles Lady Madonna Lyrics | Lyrics007</title>
<link href="/boilerplate.css" rel="stylesheet" type="text/css">
<link href="/007.css" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="/respond.min.js"></script>
</head>
<body>
<script type="text/javascript" src="/top.js"></script>
<div class="ads_728">
<script type="text/javascript">
cf_page_genre = "";
cf_adunit_id = "39380715";
</script>
<script src="//srv.clickfuse.com/showads/showad.php"></script></div>
<div class="navigate"><a href="http://www.lyrics007.com">Home</a>&nbsp;>> The Beatles - Lady Madonna Lyrics</div>
<div class="main">
<h1>The Beatles - Lady Madonna Lyrics</h1>
<div class="content">
<div style="display:block;float:right;padding-top:10px;padding-right:0px;padding-bottom:10px;"><script type="text/javascript"><!--
google_ad_client = "ca-pub-0919305250342516";
/* 160x600, created 12/9/08 */
google_ad_slot = "8583291572";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="//pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>Writer(s):LENNON, JOHN WINSTON / MCCARTNEY, PAUL JAMES<br>Artist: <a href="http://www.lyrics007.com/The%20Beatles%20Lyrics.html">The Beatles Lyrics</a>
<br>Popularity: 9957 users have visited this page.<br>Album: Track 22 on The Beatles Collection, Volume 5: Sgt. Pepper's Lonely Hearts Club Band<br>
<div itemscope itemtype="http://data-vocabulary.org/Review-aggregate">Rate:
<span itemprop="itemreviewed">Lady Madonna</span> gets avg. rating
<span itemprop="rating" itemscope itemtype="http://data-vocabulary.org/Rating">
<span itemprop="average">7.3</span>
out of <span itemprop="best">10</span>
</span> based on <span itemprop="votes">3</span> ratings. Rate the song now!!!</div>
<div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><div class=rating></div><br><br>
<div class="gridContainer clearfix">
<div style="width:100%;text-align:center;">
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- auto_size -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-0919305250342516"
data-ad-slot="9819980608"
data-ad-format="auto"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<a href="http://www.lyrics007.com">Home</a>&nbsp;>> <a href="http://www.lyrics007.com/The%20Beatles%20Lyrics.html">The Beatles Lyrics</a>&nbsp;>> The Beatles - Lady Madonna Lyrics<div id="LayoutDiv1">
<h1>The Beatles Lady Madonna Lyrics</h1>
Artist: <a href="http://www.lyrics007.com/The Beatles%20Lyrics.html">The Beatles Lyrics</a>
<br />Popularity : 2898 users have visited this page.
<br />Album: Track 22 on <i>The Beatles Collection, Volume 5: Sgt. Pepper's Lonely Hearts Club Band</i>
<br />Recorded: 3 and 6 February 1968, EMI Studios, London
<br />Writer(s): LennonMcCartney
<br />Genre: Rock and roll
<br />Producer(s): George Martin
<br />Length: 2:16
<br />Certification: Platinum (RIAA)<br />Format: 7" single
<br />Label: Parlophone (UK), Capitol (US)
<br />Released: 15 March 1968
<br /><br><br>Lady Madonna, children at your feet
<BR>
Wonder how you manage to make ends meet
<BR>
Who find the money when you pay the rent
<BR>
Did you think that money was heaven sent
<BR>
<!-- START: RTM Ad -->
<div class="rtm_ad" data-sid="LWOS" data-subtag="ros" data-artist="The Beatles" data-song="Lady Madonna" data-search="">
<!-- Note: This fail-safe link will be dynamically replaced -->
<a href="http://www.ringtonematcher.com/go/?sid=LWOS" rel="nofollow" target="_blank" style="text-decoration: none;">
<img src="//cdn.ringtonematcher.com/images/icons/phones/darkblue_left.gif" style="border-style: none; vertical-align: middle; margin-right: 5px;">
<span style="text-decoration: underline; color: red; font: bold 16px Arial; verticalalign: middle;">Send Ringtones to your Cell</span>
<img src="//cdn.ringtonematcher.com/images/icons/phones/darkblue_right.gif" style="border-style: none; verticalalign: middle; margin-left: 5px;"></a>
</div>
<!-- END: RTM Ad -->Lady Madonna, children at your feet<br />
Wonder how you manage to make ends meet<br />
Who find the money when you pay the rent<br />
Did you think that money was heaven sent<br />
<br />
Friday night arrives without a suitcase<br />
Sunday morning creeping like a nun<br />
Monday's child has learned to tie his bootlegs<br />
See how they run<br />
<br />
Lady Madonna, baby at your breast<br />
Wonders how you manage to feed the rest<br />
Pa pa pa pa,<br />
See how they run<br />
<br />
Lady Madonna lying on the bed<br />
Listen to the music playing in your head<br />
<br />
Tuesday afternoon is never ending<br />
Wednesday morning papers didn't come<br />
Thursday night you stocking needed mending<br />
See how they run<br />
<br />
Lady Madonna, children at your feet<br />
Wonder how you manage to make ends meet<br>
<!-- START: RTM Ad -->
<div class="rtm_ad" data-sid="LWOS" data-subtag="ros" data-artist="The Beatles" data-song="Lady Madonna" data-search="">
<!-- Note: This fail-safe link will be dynamically replaced -->
<a href="http://www.ringtonematcher.com/go/?sid=LWOS" rel="nofollow" target="_blank" style="text-decoration: none;">
<img src="//cdn.ringtonematcher.com/images/icons/phones/darkblue_left.gif" style="border-style: none; vertical-align: middle; margin-right: 5px;">
<span style="text-decoration: underline; color: red; font: bold 16px Arial; verticalalign: middle;">Send Ringtones to your Cell</span>
<img src="//cdn.ringtonematcher.com/images/icons/phones/darkblue_right.gif" style="border-style: none; verticalalign: middle; margin-left: 5px;"></a>
</div>
<!-- END: RTM Ad -->
<script language='javaScript' type='text/javascript'>
document.write("<img src='http://licensing.lyrics007.com/in" + "fo.php?id=1536077&referer=0'>");
</script><br>
<form action="/correct.php" method="post" id="correctit" target="_blank">
<input type="hidden" name="id" value="TXpJNU1UWXg" />
</form><br>If you believe the lyrics are not correct you can <a href="#" onclick="document.getElementById('correctit').submit();return false;">Submit Corrections</a> to us<br>Add a comment and share what The Beatles Lady Madonna Lyrics means to you with your friends:<br>
<fb:comments href="http://www.lyrics007.com/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html" num_posts="5" width="640"></fb:comments>
Featured lyrics:
<ul>
<li><a href="/Johnny%20Cash%20Lyrics/Ship%20Those%20Niggers%20Back%20Lyrics.html">Johnny Rebel - Ship Those Niggers Back Lyrics</a>
<li><a href="/Demi%20Lovato%20Lyrics/Never%20Been%20Hurt%20Lyrics.html">Demi Lovato - Never Been Hurt Lyrics</a>
<li><a href="/Blink-182%20Lyrics/Roller%20Coaster%20Lyrics.html">Blink-182 - Roller Coaster Lyrics</a>
<li><a href="/Kenny%20Chesney%20Lyrics/I%20Go%20Back%20Lyrics.html">Kenny Chesney - I Go Back Lyrics</a>
<li><a href="/Toto%20Lyrics/Hold%20The%20Line%20Lyrics.html">Toto - Hold the Line Lyrics</a>
<li><a href="/Backstreet%20Boys%20Lyrics/The%20One%20Lyrics.html">Backstreet Boys - The One Lyrics</a>
<li><a href="/Beyonce%20Lyrics/Standing%20On%20The%20Sun%20Lyrics.html">Beyonce - Standing On The Sun Lyrics</a>
<li><a href="/Johnny%20Cash%20Lyrics/A%20Thing%20Called%20Love%20Lyrics.html">Johnny Cash - A Thing Called Love Lyrics</a>
<li><a href="/Sugababes%20Lyrics/Too%20Lost%20In%20You%20Lyrics.html">Sugababes - Too Lost in You Lyrics</a>
<li><a href="/Green%20Day%20Lyrics/Paranoia%20Lyrics.html">Harvey Danger - Flagpole Sitta Lyrics</a>
</ul>Lyrics © Sony/ATV Music Publishing LLC
<br><img src="/images/LF.png">
</div>
<div class="side_bar">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-0919305250342516";
/* 300x250, created 9/18/08 */
google_ad_slot = "8367624871";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br>
<form action="/print.php" method="post" id="printit" target="_blank">
<input type="hidden" name="id" value="TXpJNU1UWXg" /></form><br><div style="width:300px;">
<div style="width: 60px; float: left;"><a class=twitter-share-button href="https://twitter.com/share" data-count="vertical" data-lang="en" data-url="http://www.lyrics007.com/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html">Tweet</a></div>
<div style="width:60px; float:right;"><a href="#" onclick="document.getElementById('printit').submit();return false;" rel="nofollow"><img src="/images/print.gif" border=0></a></div>
<div style="width:80px;padding-left:30px; float:left;">
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<g:plusone size="tall"></g:plusone></div>
<div style="width:70px; flat:left;" class="fb-like" data-href="http://www.lyrics007.com/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html" data-send="false" data-layout="box_count" data-width="70" data-show-faces="false"></div>
</div><br>More lyrics from The Beatles Collection, Volume 5: Sgt. Pepper's Lonely Hearts Club Band album<br>
<ol><li><a href="/The%20Beatles%20Lyrics/Sgt.%20Pepper's%20Lonely%20Hearts%20Club%20Band%20Lyrics.html">Sgt. Pepper's Lonely Hearts Club Band Lyrics</a><li><a href="/The%20Beatles%20Lyrics/A%20Little%20Help%20From%20My%20Friends%20Lyrics.html">With a Little Help From My Friends Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Lucy%20in%20the%20Sky%20with%20Diamonds%20Lyrics.html">Lucy in the Sky With Diamonds Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Getting%20Better%20Lyrics.html">Getting Better Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Fixing%20a%20Hole%20Lyrics.html">Fixing a Hole Lyrics</a><li><a href="/The%20Beatles%20Lyrics/She's%20Leaving%20Home%20Lyrics.html">She's Leaving Home Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Being%20For%20The%20Benefit%20Of%20Mr.%20Kite%20Lyrics.html">Being for the Benefit of Mr. Kite Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Within%20You%20Without%20You%20Lyrics.html">Within You Without You Lyrics</a><li><a href="/The%20Beatles%20Lyrics/When%20I'm%20Sixty-four%20Lyrics.html">When I'm Sixty-Four Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Lovely%20Rita%20Lyrics.html">Lovely Rita Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Good%20Morning%20Good%20Morning%20Lyrics.html">Good Morning Good Morning Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Sgt.%20Pepper's%20Lonely%20Hearts%20Club%20Band%20(Reprise)%20Lyrics.html">Sgt. Pepper's Lonely Hearts Club Band (reprise) Lyrics</a><li><a href="/The%20Beatles%20Lyrics/A%20Day%20in%20Life%20Lyrics.html">A Day in the Life Lyrics</a><li><a href="/The%20Beatles%20Lyrics/I%20Want%20To%20Hold%20Your%20Hand%20Lyrics.html">I Want to Hold Your Hand Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Long%20Tall%20Sally%20Lyrics.html">Long Tall Sally Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Yes%20It%20Is%20Lyrics.html">Yes It Is Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Day%20Tripper%20Lyrics.html">Day Tripper Lyrics</a><li><a href="/The%20Beatles%20Lyrics/We%20Can%20Work%20It%20Out%20Lyrics.html">We Can Work It Out Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Paperback%20Writer%20Lyrics.html">Paperback Writer Lyrics</a><li><a href="/The%20Beatles%20Lyrics/The%20Inner%20Light%20Lyrics.html">The Inner Light Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Revolution%20Lyrics.html">Revolution Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html">Lady Madonna Lyrics</a><li><a href="/The%20Beatles%20Lyrics/Hey%20Jude%20Lyrics.html">Hey Jude Lyrics</a></ol><script>
<BR>
Friday night arrives without a suitcase
<BR>
Sunday morning creeping like a nun
<BR>
Monday's child has learned to tie his bootlace
<BR>
See how they run
<BR>
<BR>
Lady Madonna, baby at your breast
<BR>
Wonders how you manage to feed the rest
<div class="ad300"><font color=red>sponsored links</font><br><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- l_007 -->
<ins class="adsbygoogle"
style="display:inline-block;width:300px;height:250px"
data-ad-client="ca-pub-0919305250342516"
data-ad-slot="2166102852"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<BR>
<BR>
See how they run
<BR>
<BR>
Lady Madonna lying on the bed
<BR>
Listen to the music playing in your head
<BR>
<BR>
Tuesday afternoon is never ending
<BR>
Wednesday morning papers didn't come
<BR>
Thursday night your stocking needed mending
<BR>
See how they run
<BR>
<BR>
Lady Madonna, children at your feet
<BR>
Wonder how you manage to make ends meet
<br><br>Thanks to Quidam for the correction
<div class="album_cover"><img src="/images/cover_art/80/23/9" alt="The Beatles's Lady Madonna album cover" title="The Beatles's Lady Madonna album cover"></div><center><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.lyrics007.com%2FThe%2520Beatles%2520Lyrics%2FLady%2520Madonna%2520Lyrics.html&amp;width&amp;layout=button_count&amp;action=like&amp;show_faces=false&amp;share=true&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; height:21px; width:150px;" allowTransparency="true"></iframe></center><div style="clear:both;text-align:center;"><script>
/* Lyrics007 - 300x250 - Brand Ads Only */
cf_page_artist = "The Beatles";
cf_page_song = "Lady Madonna";
cf_page_genre = "";
cf_adunit_id = "39380716";
cf_adunit_id = "39380905";
</script>
<script src="//srv.clickfuse.com/showads/showad.php"></script>
<br><br>
<script src="//srv.clickfuse.com/showads/showad.php"></script></div>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'mylyrics007'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
<br>The hottest lyrics from The Beatles<ul><ul><li><a href="/The%20Beatles%20Lyrics/Let%20it%20Be%20Lyrics.html">Let It Be Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Here%20Comes%20The%20Sun%20Lyrics.html">Here Comes the Sun Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Come%20Together%20Lyrics.html">Come Together Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Across%20The%20Universe%20Lyrics.html">Across the Universe Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/While%20My%20Guitar%20Gently%20Weeps%20Lyrics.html">While My Guitar Gently Weeps Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Yesterday%20Lyrics.html">Yesterday Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Help!%20Lyrics.html">Help! Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Revolution%20Lyrics.html">Revolution Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Hello%20Goodbye%20Lyrics.html">Hello Goodbye Lyrics</a>
<li><a href="/The%20Beatles%20Lyrics/Can't%20Buy%20Me%20Love%20Lyrics.html">Can't Buy Me Love Lyrics</a>
</ul></ul>
<br>
<script language="javascript" type="text/javascript">
document.write("<img src=\"http://licensing.lyrics007.com/info.php?id=1536077\">");
</script>
<br><img src="/images/LF.png">
</div>
</div>
<div class="bottom">Lyrics007 gets licensed to display lyrics and pay the lyrics writers through LyricFind. The most of song titles are calibrated according to wikipedia</div>
<div class="copyright">&nbsp;&copy;COPYRIGHT 2012, LYRICS007.COM, ALL RIGHTS RESERVED.</div>
<div id="myDiv"></div>
<div>&nbsp;&copy;COPYRIGHT 2014, LYRICS007.COM, ALL RIGHTS RESERVED.</div>
<!--329161-->
</div>
</body>
</html>

View file

@ -31,7 +31,7 @@ Friday night arrives without a suitc.." />
<script type="text/javascript" src="/js/mini/header.js?combined=prototype,overlay,common,lyrics,users,scriptaculous"></script>
<script type="text/javascript" src="/js/mini/header.20140417.js?combined=prototype,overlay,common,lyrics,users,scriptaculous"></script>
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript">var $j = jQuery.noConflict();</script>
@ -50,71 +50,20 @@ Friday night arrives without a suitc.." />
<script src="/js/ie6.js" type="text/javascript"></script>
<script src="/js/pngfix.js" type="text/javascript"></script>
<![endif]-->
<!-- artists lyric --><!-- SHOULD SHOW LYRICS (T 232880) --><!-- CANNOT FIND RELATED LYRICS --> <!-- LYRICS FIND -->
<!-- artists lyric --> <!-- LYRICS FIND -->
<!-- ### Put all this in the head of your page ### -->
<style type="text/css" media="screen">
.PRINTONLY {display:none;visibility:hidden;}
</style>
<style type="text/css" media="print">
.SCREENONLY {display:none;visibility:hidden;}
</style>
<script language="JavaScript1.2">
var selectdisabled = true;
var omitformtags= new Array();
omitformtags[0] = "input";
omitformtags[1] = "select";
omitformtags[2] = "textarea";
omitformtags[3] = "radio";
omitformtags[4] = "checkbox";
function disableselect(e) {
var formObj = false;
for (var i = 0; i < omitformtags.length; i++){
if (e.target.tagName.toLowerCase() == omitformtags[i]){
formObj = true;
}
}
if (!formObj){
return false;
}
}
function reEnable(){
return true;
}
if (typeof document.onselectstart != "undefined"){
document.onselectstart = new Function ("return false");
}else{
document.onmousedown=disableselect;
document.onmouseup=reEnable;
}
</script>
<script language="javascript">
/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write("<script defer src=/js/ie_onload.js><"+"/script>");
/*@end @*/
</script>
<!-- ### END ### -->
<!-- END OF LYRICS FIND -->
<!-- END OF PRESENCE BAR CSS -->
<script src="http://adexcite.com/ads/video/controller.php?eid=15200"></script>
</head>
<body onLoad="; " id="bodytag" class="bodyContent userbg" oncontextmenu="return false;" onkeydown="if(event.ctrlKey){return false;}" >
<body id="bodytag" class="bodyContent userbg" >
<div id="overlay" class="hide">
<div class="close"><a href="javascript:void(0);" onClick="ol_close();">close</a></div>
<div id="overlay_content"></div>
@ -177,112 +126,101 @@ document.getElementById('googlecseinput'),
<div class="inner">
<div id="content">
<!--<div id="content">--><script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script type="text/javascript" src="/js/mini/slimScroll.js"></script>
<script type="text/javascript" src="/js/mini/track_comments.js"></script>
<script type="text/javascript">
</script>
<!--<div id="content">--><script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script type="text/javascript" src="/js/mini/lyrics.js"></script>
<link href="/css/mini/profile-layout.css" rel="stylesheet" type="text/css" />
<link href="/css/mini/lyrics.css?20131003-2" rel="stylesheet" type="text/css" />
<link href="/css/mini/lyrics.20140428.css" rel="stylesheet" type="text/css" />
<style>
h1#profile_name, h1#profile_name * { font-size:16px; }
#songlist .row { border-bottom:1px solid #ccc; padding-bottom:5px; margin-bottom:5px; }
#songlist .row .left { clear:both; float:none; }
#songlist .row .left a { color:#555; }
#menu ul, #menu li { list-style-type:none; padding:0px; margin:0px; }
#menu ul li { display:block; }
#menu ul li a { padding:5px; border:1px solid #ccc; display:block; width:148px; color:#333; text-align:center; }
#menu ul li a:hover { color:#333; }
#leftcontent {
position: relative;
}
#leftcontent .btn_right {
width: auto !important;
}
.fblike_btn {
width: 130px;
}
#adbox { width: 444px; }
</style>
<div id="outer_profile">
<div id="pic_ads">
<a href="thebeatles"><img src='http://image01.lyrics.com/artists/pic200/drP900/P970/p97040d4dv8.jpg' width='160' border='1' alt='thebeatles' /></a>
<br />
<div id="menu">
<ul>
<li><span id="friend_artist_link_P 3644"><a href='javascript:void(0);' onclick="return alert('Please login first.');">Follow</a></span></li>
<li><a href="/artists/artist_fans/P 3644">Fans</a></li>
<li><a href="/artists/albums/P 3644">Albums</a></li>
<li><a href="/thebeatles">Lyrics</a></li>
</ul> </div>
<div id="google_ads_160x600">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-3044889097204573";
/* 160x600, created 9/9/08 */
google_ad_slot = "3524097094";
google_ad_width = 160;
google_ad_height = 600;
//-->
<script async src="http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:inline-block;width:160px;height:600px"
data-ad-client="ca-pub-3044889097204573"
data-ad-slot="3524097094"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</div>
</div>
<div id="profile">
<div id="leftcontent">
<script type="text/javascript">
function toggleYouTube()
{
var youtube = '<iframe src="http://www.pages.com/youtube.php?T_ID=T 232880&width=420&height=236" width="420" height="236" frameborder="0"></iframe>';
$('adbox').innerHTML = youtube;
}
</script>
<div id="adbox">
<!--The Beatles - Lady Madonna-->
<div id="fake_youtube" class="image">
<div id="fake_image"><a href="#" onclick="return toggleYouTube();"><img src="http://img.youtube.com/vi/gNyHymEhZmg/0.jpg" width="420" height="236" /></a></div>
<div id="fake_play_btn"><a href="#" onclick="return toggleYouTube();"><img src="/images/play_overlay_white.png" /></a></div>
</div>
</div><br />
<table width="420" cellpadding="0" cellspacing="0" class="playlist-btn">
<tr>
<td width="396">
<a href='http://www.lyrics.com/login_redirect.php?u=%2Flady-madonna-lyrics-the-beatles.html' class='silver_btn_left' onclick="alert('Please login first to add this song into your playlist!');" title='Add to playlist'>Add to Playlist</a> </td>
<td width="24">
<a class="silver_btn_right" href="javascript:void(0);" onclick="flagVideo('T 232880');">&nbsp;</a>
</td>
</table>
<br />
<div class="leftbox">
<div class="title">
<div class="left">Suggestions</div>
<div class="right">&nbsp;</div>
<br style="clear:both" />
</div>
<div class="content">
<div class="row" id="album_list">
</div>
<script type="text/javascript">
getTopSongsMore('/home/similarsongs_left_start/T 232880/0');
<script type="text/javascript">
function toggleYouTube()
{
var youtube = '<iframe src="http://www.pages.com/youtube.php?T_ID=T 232880&width=444&height=250" width="444" height="250" frameborder="0"></iframe>';
$j('#adbox_temp').addClass('hide');
$('adbox_content').innerHTML = youtube;
$j('#adbox').removeClass('hide');
}
</script>
</div>
</div>
<div class='pw-widget pw-size-medium'>
<a class='pw-button-googleplus'></a>
<a class='pw-button-facebook'></a>
<a class='pw-button-twitter'></a>
<a class='pw-button-email'></a>
<a class='pw-button-post'></a>
</div>
<script src='http://i.po.st/static/script/post-widget.js#publisherKey=ahap795vm5td5n4ua63f' type='text/javascript'></script>
<div id="adbox_temp">
<script>
/* 300 x 250 Medium Rectangle / 300x600 Hybrid */
cf_page_artist = "The Beatles";
cf_page_song = "Lady Madonna";
cf_adunit_id = "39382430";
</script>
<script src="//srv.clickfuse.com/showads/showad.js"></script>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- ros300x250new -->
<ins class="adsbygoogle"
style="display:inline-block;width:300px;height:250px"
data-ad-client="ca-pub-3044889097204573"
data-ad-slot="7302685429"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
<div id="adbox" class="hide">
<div id="adbox_content">
</div>
<div class="btn_right">
<a href='javascript:void(0);' class="silver_btn_default refresh_video" title="Get New Video">
Get New Video
</a>
</div>
</div><br />
</div>
<div id="rightcontent">
<div class="profile_name_and_status">
<h1 id="profile_name">Lady Madonna<br /><span class="small">by <a href="/thebeatles">The Beatles</a></span></h1>
<div class="fblike_btn">
<iframe src="http://www.facebook.com/plugins/like.php?app_id=257638770934394&amp;href=http%3A%2F%2Fwww.lyrics.com%2F%2Flady-madonna-lyrics-the-beatles.html&amp;send=false&amp;layout=button_count&amp;width=90&amp;show_faces=true&amp;action=like&amp;colorscheme=light&amp;font&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<a href='http://www.lyrics.com/login_redirect.php?u=%2Flady-madonna-lyrics-the-beatles.html' class='silver_btn_default' onclick="alert('Please login first to add this song into your playlist!');" title='Add to playlist'>Add to Playlist</a> <a href='javascript:void(0);' onclick="toggleYouTube();"><img src='http://www.lyrics.com/images/play.png' alt='play' align="absmiddle" /></a>
</div>
</div>
<div class="tabs_wrapper">
@ -293,8 +231,17 @@ document.getElementById('googlecseinput'),
<div id="lyric_tab_content" class="tab_content">
<div id="lyric_tab_content" class="tab_content" style="position:relative;">
<div style="position:absolute;top:0;right:0;z-index:10;">
<div class="pw-widget pw-vertical pw-size-medium">
<a class="pw-button-facebook"></a>
<a class="pw-button-twitter"></a>
<a class="pw-button-googleplus"></a>
<a class="pw-button-print"></a>
</div>
<script src="http://i.po.st/static/v3/post-widget.js#publisherKey=ahap795vm5td5n4ua63f&retina=true" type="text/javascript"></script>
</div>
<div class="artist_content">
@ -303,10 +250,22 @@ document.getElementById('googlecseinput'),
<div class="ringtone_area"><strong><img src="/images/phone__left.gif" border='0' />&nbsp;
<a href="http://www.ringtonematcher.com/go/?sid=PALYros&&artist=The+Beatles&song=Lady+Madonna" rel="nofollow" target="_blank">
Send "Lady Madonna" Ringtone to your Cell
</a>&nbsp;<img src="/images/phone__right.gif" border='0' /></strong></div> <!-- LYRIC REVISION FORM -->
<script>
/* Above Lyrics */
cf_page_artist = "The Beatles";
cf_page_song = "Lady Madonna";
cf_adunit_id = "39382166";
cf_hostname = "srv.tonefuse.com";
</script>
<div class="tonefuse"></div>
<!-- LYRIC REVISION FORM -->
<div id="revision_form" class="hide">
</div>
@ -341,17 +300,15 @@ See how they run<br />
<br />
Lady Madonna, children at your feet<br />
Wonder how you manage to make ends meet<br />---<br />Lyrics powered by <a href="http://www.lyricfind.com" target="_blank" rel="nofollow" style="color:#000; text-decoration:none; cursor:text">LyricFind</a><br />
written by LENNON, JOHN WINSTON / MCCARTNEY, PAUL JAMES<br />
written by LENNON, JOHN / MCCARTNEY, PAUL<br />
Lyrics © Sony/ATV Music Publishing LLC<!-- RESPONSE CODE: 101 ** 232880 --><!-- T_ID: T 232880 --> </div>
</div>
<!-- LYRIC REVISION -->
<div class="ringtone_area"><strong><img src="/images/phone__left.gif" border='0' />&nbsp;
<a href="http://www.ringtonematcher.com/go/?sid=PALYros&artist=The+Beatles&song=Lady+Madonna" rel="nofollow" target="_blank">
Send "Lady Madonna" Ringtone to your Cell
</a>&nbsp;<img src="/images/phone__right.gif" border='0' /></strong></div>
<div class="tonefuse_bottom"></div>
</div>
@ -386,7 +343,44 @@ Wonder how you manage to make ends meet<br />---<br />Lyrics powered by <a href=
<br style="clear:both;" />
</div>
</div><!-- #outer_profile -->
<div id="tonefuse_content" style="display:none;">
<script src="//srv.tonefuse.com/showads/showad.js"></script>
</div>
<div id="tonefuse_bottom_content" style="display:none;">
<script>
/* Below Lyrics */
(function() {
var opts = {
artist: "The Beatles",
song: "Lady Madonna",
adunit_id: 39382167,
div_id: "cf_async_" + Math.floor((Math.random() * 999999999)),
};
document.write('<div id="'+opts.div_id+'"></div>');var c=function(){cf.showAsyncAd(opts)};if(window.cf)c();else{cf_async=!0;var r=document.createElement("script"),s=document.getElementsByTagName("script")[0];r.async=!0;r.src="//srv.tonefuse.com/showads/showad.js";r.readyState?r.onreadystatechange=function(){if("loaded"==r.readyState||"complete"==r.readyState)r.onreadystatechange=null,c()}:r.onload=c;s.parentNode.insertBefore(r,s)};
})();
</script>
</div>
<script type="text/javascript">
function addToneFuseContent() {
var html = $j('#tonefuse_content').html();
if(html.search('/style') > -1) {
var content = $j("#tonefuse_content").clone().find("script,noscript").remove().end().html();
$j('.tonefuse').html(content);
} else {
setTimeout(200,addToneFuseContent);
}
}
addToneFuseContent();
function addToneFuseBottomContent() {
var html = $j('#tonefuse_bottom_content').html();
if(html.search('cf_async') > -1) {
var content = $j("#tonefuse_bottom_content").clone().find("script,noscript").remove().end().html();
$j('.tonefuse_bottom').html(content);
} else {
setTimeout(200,addToneFuseBottomContent);
}
}
addToneFuseBottomContent();
var lyricform = false;
function showRevisionForm()
{
@ -430,11 +424,25 @@ function add_lyric_comment()
}});
return false;
}
Event.observe(window,'load',function() {
});
var minTop = 65;
$j(document).ready(function() {
});
$j(window).scroll(function() {
var scrollTop = $j(window).scrollTop();
if(scrollTop <= minTop) {
$j('#adbox').css({ position: 'relative', top: '0px', width: '444px' });
} else {
$j('#adbox').css({ position: 'fixed', top: '10px', width: '444px' });
}
});
$j('.refresh_video').click(function(e) {
lyricPageFlagVideo('T 232880');
e.preventDefault();
</script>
<br class="clear" />
});
</script> <br class="clear" />
</div><!-- #content -->
</div><!-- #inner -->
@ -460,7 +468,7 @@ Event.observe(window,'load',function() {
<a href='/about/contact'>Contact Us</a> | <a href='/about/terms_of_use'>Terms of Use</a> | <a href='/about/privacy'>Privacy Policy</a> | <a href="/user/api/docs/">Developers</a>
</td>
<td style="text-align:right;">
&copy; 2008 Lyrics.com | All rights reserved. | 0.2153()<!-- --> </td>
&copy; 2008 Lyrics.com | All rights reserved. | 0.2034()<!-- --> </td>
</tr>
</table>
</div>
@ -501,8 +509,7 @@ Event.observe(window,'load',function() {
<img src="http://b.scorecardresearch.com/p?c1=2&c2=6035055&c3=&c4=&c5=&c6=&c15=&cj=1" />
</noscript>
<!-- End comScore Tag -->
</body>
</body>
</html>

View file

@ -1,812 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Lilly Wood & The Prick - Hey It's Ok Lyrics</title>
<link href="/files/aa2.css" type=text/css rel=stylesheet>
<meta name="description" content="Lilly Wood & The Prick Hey It's Ok Lyrics. Hey It's Ok lyrics performed by Lilly Wood & The Prick: Mama, Papa, please forget the times <br />
I wet my bed <br />
I swear not to do it again <br />
Please forgive the way I looked <br />
" />
<meta name="keywords" content="hey it's ok,lilly wood & the prick,lyrics,words,song" />
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<meta name="language" content="en" />
<meta property="og:title" content="Lilly Wood & The Prick - Hey It's Ok Lyrics"/>
<meta property="og:type" content="song"/>
<meta property="og:url" content="http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html"/>
<meta property="og:site_name" content="www.lyricsmania.com"/>
<meta property="og:description" content="Lilly Wood & The Prick Hey It's Ok Lyrics. Hey It's Ok lyrics performed by Lilly Wood & The Prick: Mama, Papa, please forget the times <br />
I wet my bed <br />
I swear not to do it again <br />
Please forgive the way I looked <br />
">
<meta property="og:language" content="en"/>
<meta property="fb:admins" content="100001599431689" />
<meta http-equiv="expires" content="0" />
<meta name="classification" content="Lilly Wood & The Prick lyrics" />
<link href="http://www.lyricsmania.com/xml/last100album.xml" rel="alternate" type="application/rss+xml" title="Last 100 Albums" />
<link href="http://www.lyricsmania.com/xml/last100artists.xml" rel="alternate" type="application/rss+xml" title="Last 100 Artists" />
<link href="http://www.lyricsmania.com/xml/last100lyrics.xml" rel="alternate" type="application/rss+xml" title="Last 150 Lyrics" />
<script type="text/javascript" src="/js/lm_js.js"></script>
<script type="text/javascript" src="http://partner.googleadservices.com/gampad/google_service.js">
</script>
<script type="text/javascript">
GS_googleAddAdSenseService("ca-pub-3687873374834629");
GS_googleEnableAllServices();
</script>
<script type="text/javascript">
GA_googleUseIframeRendering();
GA_googleAddAttr("j_title", "Hey It's Ok");
GA_googleAddAttr("j_artist", "Lilly Wood & The Prick");
</script>
<link rel="image_src" href="/files/toplogo4.jpg" />
<script language="javascript" type="text/javascript" src="/copy.js"></script>
<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
{lang: 'en'}
</script>
<link rel="canonical" href="http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html">
<link rel="alternate" hreflang="it" href="http://www.testimania.com/" />
<link rel="alternate" hreflang="es" href="http://www.letrasmania.com/" />
<link rel="alternate" hreflang="fr" href="http://www.parolesmania.com/" />
<link rel="alternate" hreflang="de" href="http://www.songtextemania.com/" />
<script type="text/javascript">
window.___gcfg = {lang: 'en'};
(function()
{var po = document.createElement("script");
po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(po, s);
})();</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-435431-1']);
_gaq.push(['_setDomainName', 'lyricsmania.com']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<script>
cf_page_artist = "Lilly Wood & The Prick";
cf_page_song = "Hey It's Ok";
cf_page_genre = "";
cf_adunit_id = "39381134";
cf_flex = true;
</script>
<script src="//srv.clickfuse.com/showads/showad.php"></script>
<script type="text/javascript">
function toolbar(id_el,id_eldue) {
el = document.getElementById(id_el);
eldue = document.getElementById(id_eldue);
_display = (el.style.display);
if (_display == "none") {
eldue.style.bottom = "-60px";
eldue.style.display = "none";
el.style.display = "block";
setTimeout(function(){slide(el)},2);
}
else {
el.style.display = "none";
eldue.style.display = "block";
}
}
function slide(id_el) {
if(!id_el.id) {
el = document.getElementById(id_el);
}
_bottom = parseInt(el.style.bottom);
if (_bottom < '0') {
el.style.bottom = (_bottom+2)+"px";
setTimeout(function(){slide(id_el)},5);
}
}
</script>
<script type='text/javascript' language='javascript'>
var cw = 1003; // specify content width
var cp = 10; // specify the content padding if desired
try{
var s=document.createElement('script');
s.id='specific_rome_js';
s.type='text/javascript';
s.src='http://rome.specificclick.net/rome/rome.js?l=31116&t=j&cw='+cw+'&cp='+cp;
document.body.appendChild(s);
}catch(e){}
</script></head>
<body id=page_bg>
<h1>Hey It's Ok Lyrics</h1>
<div class=center align=center style="margin-bottom: 49px;">
<!-- Inizio Header -->
<div id=aa>
<div id=aa1><a href="/" title="lyrics"><img src="/blank.gif" alt="lyrics" border="0" height="95" width="242"></a></div>
<div id=aa2>
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4710666039840396";
google_ad_slot = "4552504620/6029212500";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="//pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div id=aa3></div>
</div>
<!-- Fine Header -->
<div class=clr></div>
<div id=sx>
<div id=dx>
<div id=tabs>
<div id=tabssx>
<div id=tabsdx>
<div id=tabber>
<ul>
<li class=blue><a href="http://www.lyricsmania.com/">Lyrics</a></li>
<li class=blue><a href="/soundtrackslyrics.html">Soundtrack Lyrics</a></li>
<li class=blue><a href="/topartists.html">Top 100 Artists</a></li>
<li class=blue><a href="/toplyrics.html">Top 100 Lyrics</a></li>
<li class=blue><a href="/last100artists.html">Last 100 artists</a></li>
<li class=blue><a href="/last100album.html">Last 100 albums</a></li>
<li class=blue><a href="/add.html">Submit Lyrics</a></li>
<li>
<form class="logina" action="http://my.lyricsmania.com/login.php?destpage=/hey_its_ok_lyrics_lilly_wood_and_the_prick.html">
<input class="formino" type="text" name="username" size="9" maxlength="18" value="Username" onFocus="if(this.value == 'Username') {this.value = '';}" onBlur="if (this.value == '') {this.value = 'Username';}" />
<input class="formino" type="password" name="password" size="9" maxlength="18" value="Password" onFocus="if(this.value == 'Password') {this.value = '';}" onBlur="if (this.value == '') {this.value = 'Password';}" />
<input class="loginb" type="submit" value="Login"> or
</form>
</li>
<li class=beige><a href="http://my.lyricsmania.com/signup.html">Signup</a> </li>
</ul>
</div>
</div>
</div>
</div>
<div class=clr></div>
<!-- Inizio Blocco Contenuti -->
<div id=topmodule></div>
<div id=whitebox>
<div id=whitebox_t>
<div id=whitebox_tl>
<div id=whitebox_tr></div></div></div>
<div id=whitebox_m>
<div id=area>
<div id=maincolumn2>
<div id=albums>
<table cellpadding="2" cellspacing="0" width="100%">
<tr>
<td align=center>
<table>
<tr>
<td>
<form action="/searchnew.php">
<input id="s" type="text" name="k" onclick="if (this.value == 'Find Artist and/or Lyrics') this.value=''" value="Find Artist and/or Lyrics" onblur="if(this.value == '') this.value='Find Artist and/or Lyrics'" value="" style="margin:0;padding-left:2px;color:#35456e;font-size:22px;text-weight:bold;width:380px;height:30px;border: 2px solid #35456e;">
</td>
<td>
<input type="image" src="/sbut.png" value="Search!">
</td>
</tr>
</table>
</form> </td>
</tr>
<tr>
<td noWrap align=center>
<font style="color:#1b57b1; font-size: 1.0em !important;">Browse :</font>
<a href="/lyrics/num.html">0-9</a>
<a href="/lyrics/A.html">A</a>
<a href="/lyrics/B.html">B</a>
<a href="/lyrics/C.html">C</a>
<a href="/lyrics/D.html">D</a>
<a href="/lyrics/E.html">E</a>
<a href="/lyrics/F.html">F</a>
<a href="/lyrics/G.html">G</a>
<a href="/lyrics/H.html">H</a>
<a href="/lyrics/I.html">I</a>
<a href="/lyrics/J.html">J</a>
<a href="/lyrics/K.html">K</a>
<a href="/lyrics/L.html">L</a>
<a href="/lyrics/M.html">M</a>
<a href="/lyrics/N.html">N</a>
<a href="/lyrics/O.html">O</a>
<a href="/lyrics/P.html">P</a>
<a href="/lyrics/Q.html">Q</a>
<a href="/lyrics/R.html">R</a>
<a href="/lyrics/S.html">S</a>
<a href="/lyrics/T.html">T</a>
<a href="/lyrics/U.html">U</a>
<a href="/lyrics/V.html">V</a>
<a href="/lyrics/W.html">W</a>
<a href="/lyrics/X.html">X</a>
<a href="/lyrics/Y.html">Y</a>
<a href="/lyrics/Z.html">Z</a>
<font style="color:#1b57b1; font-size: 1.0em !important;"> | </font> <a href="/all.html">ALL</a>
<br /><br />
</td>
</tr>
</table>
<div class=thinbox>
<div>
<div>
<div>
<table width="100%"><tr>
<td valign="top">
<h2>Hey It's Ok lyrics</h2>
<h3>Lilly Wood & The Prick</h3>
<br />
<a href="/correct.php?id=1069996"><img src="/files/correct.png" width=16 height=16 alt="Correct Hey It's Ok Lyrics" border=0> Correct these lyrics</a><br />
<a href="/print/1069996.html" rel="nofollow" onclick="javascript: pageTracker._trackPageview('/print-testo');"><img src="/files/print.png" width=16 height=16 alt="Print Hey It's Ok Lyrics" border=0> Print these lyrics</a>
<br />
<a href="#commentlyrics" rel="nofollow"><img src="/images/pencil2.png" width=16 height=16 alt="Comment Lyrics" border=0>Comment lyrics</a><br>
<a href="http://del.icio.us/post?url=http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html" rel="nofollow" target="_blank" title="Share this page on Del.icio.us"><img src="/images/deliciousoff.png" border="0"></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&bkmk=http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html&title=LYRICS" rel="nofollow" target="_blank" title="Share this page on Google Bookmarks"><img src="/images/googleoff.png" border="0"></a>
<a href="http://digg.com/submit?phase=2&url=http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html" rel="nofollow" target="_blank" title="Share this page on Digg"><img src="/images/diggoff.png" border="0"></a>
<a href="http://www.myspace.com/Modules/PostTo/Pages/?u=http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html" rel="nofollow" target="_blank" title="Share this page on Myspace"><img src="/images/myspaceoff.png" border="0"></a>
</td>
<td width="180" valign="top">
<div class="radio">
<span class="charts">Rate this song:</span>
<form method="post" name="addme" action="http://my.lyricsmania.com/vote.html">
<input type="hidden" name="id_artista" value="57989">
<input type="hidden" name="id_testo" value="1069996">
<input type="radio" name="voto" value="1" onclick="this.form.submit()" />1
<input type="radio" name="voto" value="2" onclick="this.form.submit()" />2
<input type="radio" name="voto" value="3" onclick="this.form.submit()" />3
<input type="radio" name="voto" value="4" onclick="this.form.submit()" />4
<input type="radio" name="voto" value="5" onclick="this.form.submit()" />5
</form>
<div class="notes">
No votes yet, be the first!
<br/><br/>
<a href="http://my.lyricsmania.com/playlist/add/.html"><img src="/files/addfavorites.png" border="0"></a> <a href="http://my.lyricsmania.com/playlist/add/1069996.html">Add to my playlist</a>
</div>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class=clr></div>
<table width=100%><tr><td>
Artist: <b><a href="http://www.lyricsmania.com/lilly_wood_and_the_prick_lyrics.html" title="Lilly Wood & The Prick lyrics">Lilly Wood & The Prick lyrics</a></b><br>
Title: Hey It's Ok</td>
<td width=70>
<iframe src="http://www.facebook.com/plugins/like.php?href=http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html&amp;send=false&amp;layout=box_count&amp;width=100&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:85px; height:65px;" allowTransparency="true"></iframe>
</td>
<td width=70>
<a href="http://twitter.com/share" class="twitter-share-button" data-count="vertical" data-via="lyricsmaniacom">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
</td>
<td width=70>
<g:plusone size="tall" href="http://www.lyricsmania.com/hey_its_ok_lyrics_lilly_wood_and_the_prick.html"></g:plusone>
</td>
</tr></table>
<br>
<center>
<span style="font-size:14px;">
<a href="/redir.php?id=7&artist=Lilly Wood & The Prick&song=Hey It's Ok" target="_blank" onclick="javascript: pageTracker._trackPageview('/tonefuset1');"><img src="/images/phone_icon_red_small_trans.gif" border="0"></a>
<a href="/redir.php?id=7&artist=Lilly Wood & The Prick&song=Hey It's Ok" target="_blank" style="color: #cc0000; font-weight: bold; font-family: Arial; text-decoration: underline;" onclick="javascript: pageTracker._trackPageview('/tonefuset1');">Send "Hey It's Ok" to your Cell</a>
<a href="/redir.php?id=7&artist=Lilly Wood & The Prick&song=Hey It's Ok" target="_blank" onclick="javascript: pageTracker._trackPageview('/tonefuset1');"><img src="/images/phone_icon_red_small_trans2.gif" border="0"></a>
</span>
</center>
<br>
<div style="clear: both; overflow: hidden; text-align:center;">
<a href="http://www.musictory.com/music/Lilly+Wood+%5Band%5D+The+Prick/Hey+It%27s+Ok" target="_blank"><img src="/bottone3.png" style="vertical-align: bottom; margin-right:5px;"></a>
<a href="http://www.musictory.com/music/Lilly+Wood+%5Band%5D+The+Prick/Hey+It%27s+Ok" target="_blank">Watch "Hey It's Ok" video</a><a href="http://www.musictory.com/music/Lilly+Wood+%5Band%5D+The+Prick/Hey+It%27s+Ok" target="_blank"><img src="/bottone3.png" style="vertical-align: bottom; margin-left:5px;"></a>
</div>
<br>
<div class="other-lyrics">
<strong>Other Lilly Wood & The Prick Lyrics:</strong><br><br>
<a href="/down_the_drain_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Down the Drain lyrics</a>
<a href="/this_is_a_love_song_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">This Is A Love Song lyrics</a>
<a href="/my_best_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">My Best lyrics</a>
<a href="/cover_my_face_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Cover My Face lyrics</a>
<a href="/water_ran_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Water Ran lyrics</a>
<a href="/prayer_in_c_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Prayer In C lyrics</a>
<a href="/little_johnny_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Little Johnny lyrics</a>
<a href="/middle_of_the_night_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Middle Of The Night lyrics</a>
<a href="/a_time_is_near_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">A Time Is Near lyrics</a>
<a href="/down_the_drain_demo_version_lyrics_lilly_wood_and_the_prick.html" onclick="javascript: pageTracker._trackPageview('/other-lyrics-alto');">Down The Drain (Demo Version) lyrics</a>
</div> <!-- other -->
<strong>Lyrics to Hey It's Ok</strong> :<br />
<div id='songlyrics_h' class='dn'>
Mama, Papa, please forget the times <br />
I wet my bed <br />
I swear not to do it again <br />
Please forgive the way I looked <br />
when I was fourteen <br />
I didn't know who I wanted to be <br />
<br />
Hey It's OK, It's OK <br />
Cause I've found what i wanted <br />
Hey It's OK, I'ts Ok <br />
Cause I've found what i wanted <br />
<br />
Friends and lovers please forgive <br />
the mean things I've said <br />
I swear not to do again <br />
Please forgive the way I act when <br />
I've had too much to drink <br />
I'm fighting against myself <br />
<br />
Hey It's OK, It's OK <br />
Cause I've found what i wanted <br />
Hey It's OK, I'ts Ok<br />
<br />
Cause I've found what i wanted <br />
<br />
And I swear not to do anything funny anymore <br />
yes I swear not to do anything funny anymore <br />
<br />
Hey It's OK, It's OK <br />
Cause I've found what i wanted <br />
Hey It's OK, I'ts Ok <br />
Cause I've found what i wanted <br />
Hey It's OK, It's OK <br />
Cause I've found what i wanted <br />
Hey It's OK, I'ts Ok <br />
Cause I've found what i wanted<br />
<br />
(Merci à Julia pour cettes paroles)<br />
</div>
<script type="text/javascript">
var song_id = "";
var youtube_video = false;
var lv_code = "";
var l_code = "";
var v_code = "";
</script>
<div id="songlyrics"></div>
<script type="text/javascript">
gE('songlyrics').innerHTML = gE('songlyrics_h').innerHTML;
if (typeof startSignatureInsert === 'function')
{
startSignatureInsert();
}
</script>
<br />&#91; These are <a href="hey_its_ok_lyrics_lilly_wood_and_the_prick.html" title="Hey It's Ok Lyrics">Hey It's Ok Lyrics</a> on http://www.lyricsmania.com/ &#93;
<br><br>
<script>
google_ad_client = 'ca-pub-2633654272685046';
google_ad_channel = '1908251867';
google_override_format = 'true';
google_ad_width = 430;
google_ad_height = 80;
google_ad_type = 'text/image';
google_color_link = '#0057DA';
google_color_url = '#000000';
google_color_url = '#000000';
google_language = 'en';
</script>
<script src="https://pagead2.googlesyndication.com/pagead/show_ads.js
"></script>
<br><br>
<center>
<span style="font-size:14px;">
<a href="/redir.php?id=7&artist=Lilly Wood & The Prick&song=Hey It's Ok" target="_blank" onclick="javascript: pageTracker._trackPageview('/tonefuset2');"><img src="/images/phone_icon_red_small_trans.gif" border="0"></a>
<a href="/redir.php?id=7&artist=Lilly Wood & The Prick&song=Hey It's Ok" target="_blank" style="color: #cc0000; font-weight: bold; font-family: Arial; text-decoration: underline;" onclick="javascript: pageTracker._trackPageview('/tonefuset2');">Send "Hey It's Ok" to your Cell</a>
<a href="/redir.php?id=7&artist=Lilly Wood & The Prick&song=Hey It's Ok" target="_blank" onclick="javascript: pageTracker._trackPageview('/tonefuset2');"><img src="/images/phone_icon_red_small_trans2.gif" border="0"></a>
</span>
</center>
<div class="clr"></div>
<br>
<div class=thinbox>
<div>
<div>
<div>
<h5><a name="commentlyrics">Comments to these lyrics</a></h5>
<br />
<a href="javascript:void(0);" onclick="popolaDiv('comment_post','leave_comment')" id="leave_comment">Leave a Comment</a><br />
<div id="comment_post" style="display: none;">
<form method=post action="http://my.lyricsmania.com/login.php?destpage=/comments/add.html" id="add_comment_form" name="add_comment_form" onSubmit="validateForm(add_comment_form.comment)">
<input type="hidden" name="id_testo" value="1069996">
<textarea type=text maxlenght=50 rows="5" cols="33" wrap="virtual" name="comment" onKeyDown="limitText(this.form.comment,this.form.countdown,500);"
onKeyUp="limitText(this.form.comment,this.form.countdown,500);"></textarea><br /><font size="1">(Maximum characters: 500)<br>
You have <input readonly type="text" name="countdown" size="3" value="500"> characters left.</font>
<br />
Verification: <input type="text" name="verification"><br>Enter the text in the image
<br>
<img border="0" src="/captcha.php">
<br>
<input type="submit" name="add_comment" value="Add Comment" id="submit_comment"> </form>
</div>
<br />
No comments to these lyrics yet, be the first!
</div>
</div>
</div>
</div>
<div></div>
</div>
<div id=rectangle>
<div style='margin-bottom: 10px'>
<script type="text/javascript"><!--
e9 = new Object();
e9.size = "300x250";
e9.addBlockingCategories="Audio,Pop-under,Pop-up";
//--></script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/LyricsMania/ROS/tags.js"></script></div>
<div id="fb-root"></div>
<script>
/*
window.fbAsyncInit = function() {
FB.init({
appId : '137256903140676',
channelUrl : '//www.facebook.com/pages/Lyrics-Mania/144174245625143',
status : true,
xfbml : true
});
}
;*/
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<div class="thinbox">
<div>
<div>
<div>
<iframe src="http://www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Fpages%2FLyrics-Mania%2F144174245625143&amp;width=292&amp;colorscheme=light&amp;show_faces=true&amp;stream=false&amp;header=false&amp;height=258" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:292px; height:258px;" allowTransparency="true"></iframe>
<div class="g-plus" data-href="https://plus.google.com/112654762505809752225?rel=publisher" data-width="300" data-height="69" data-theme="light"></div>
</div>
</div>
</div>
</div><div class=thinbox>
<div>
<div>
<div>
<h5>Last Added Lyrics</h5>
<a href="/les_artistes_lyrics_lilly_wood_and_the_prick.html">L.E.S. Artistes lyrics</a><br>
<a href="/a_time_is_near_lyrics_lilly_wood_and_the_prick.html">A Time Is Near lyrics</a><br>
<a href="/long_way_back_lyrics_lilly_wood_and_the_prick.html">Long Way Back lyrics</a><br>
<a href="/middle_of_the_night_lyrics_lilly_wood_and_the_prick.html">Middle Of The Night lyrics</a><br>
<a href="/hymn_to_my_invisible_friend_lyrics_lilly_wood_and_the_prick.html">Hymn To My Invisible Friend lyrics</a><br>
<a href="/this_is_a_love_song_lyrics_lilly_wood_and_the_prick.html">This Is A Love Song lyrics</a><br>
<a href="/go_slow_lyrics_lilly_wood_and_the_prick.html">Go Slow lyrics</a><br>
<a href="/les_artistes_lyrics_lilly_wood_and_the_prick.html">L.e.s Artistes lyrics</a><br>
<a href="/down_the_drain_demo_version_lyrics_lilly_wood_and_the_prick.html">Down The Drain (Demo Version) lyrics</a><br>
<a href="/hymn_to_my_invisble_friend_lyrics_lilly_wood_and_the_prick.html">Hymn To My Invisble Friend lyrics</a><br>
<a href="/a_time_is_near_lyrics_lilly_wood_and_the_prick.html">A Time Is Near lyrics</a><br>
<a href="/hopeless_kids_lyrics_lilly_wood_and_the_prick.html">Hopeless Kids lyrics</a><br>
<a href="/little_johnny_lyrics_lilly_wood_and_the_prick.html">Little Johnny lyrics</a><br>
<a href="/my_best_lyrics_lilly_wood_and_the_prick.html">My Best lyrics</a><br>
<a href="/prayer_in_c_lyrics_lilly_wood_and_the_prick.html">Prayer In C lyrics</a><br>
</div>
</div>
</div>
</div><div class=thinbox>
<div>
<div>
<div>
<h5>Last 20 Artists</h5>
<a href="/traucoholik_lyrics.html" title="Traucoholik lyrics">Traucoholik lyrics</a> |
<a href="/mitochondrion_lyrics.html" title="Mitochondrion lyrics">Mitochondrion lyrics</a> |
<a href="/leela_and_the_rams_lyrics.html" title="Leela and The Rams lyrics">Leela and The Rams lyrics</a> |
<a href="/mariana_caetano_lyrics.html" title="Mariana Caetano lyrics">Mariana Caetano lyrics</a> |
<a href="/dosfire_lyrics.html" title="Dosfire lyrics">Dosfire lyrics</a> |
<a href="/kapone47_lyrics.html" title="Kapone47 lyrics">Kapone47 lyrics</a> |
<a href="/2anormal_lyrics.html" title="2anormal lyrics">2anormal lyrics</a> |
<a href="/poetic_teacher_lyrics.html" title="Poetic Teacher lyrics">Poetic Teacher lyrics</a> |
<a href="/stefano_bittelli_lyrics.html" title="Stefano Bittelli lyrics">Stefano Bittelli lyrics</a> |
<a href="/skeme_lyrics.html" title="Skeme lyrics">Skeme lyrics</a> |
<a href="/monica_sannino_lyrics.html" title="Monica Sannino lyrics">Monica Sannino lyrics</a> |
<a href="/mariachiara_castaldi_lyrics.html" title="Mariachiara Castaldi lyrics">Mariachiara Castaldi lyrics</a> |
<a href="/le_sparole_lyrics.html" title="Le Sparole lyrics">Le Sparole lyrics</a> |
<a href="/marco_colonna_lyrics.html" title="Marco Colonna lyrics">Marco Colonna lyrics</a> |
<a href="/lorenzo_luraca_lyrics.html" title="Lorenzo Luracà lyrics">Lorenzo Luracà lyrics</a> |
<a href="/eddi_santiago_figueroa_montes_lyrics.html" title="Eddi Santiago Figueroa Montes lyrics">Eddi Santiago Figueroa Montes lyrics</a> |
<a href="/valentina_livi_lyrics.html" title="Valentina Livi lyrics">Valentina Livi lyrics</a> |
<a href="/gabriele_morini_lyrics.html" title="Gabriele Morini lyrics">Gabriele Morini lyrics</a> |
<a href="/francesco_palma_lyrics.html" title="Francesco Palma lyrics">Francesco Palma lyrics</a> |
<a href="/violetta_zironi_lyrics.html" title="Violetta Zironi lyrics">Violetta Zironi lyrics</a> |
</div>
</div>
</div>
</div>
<div class=clr></div>
</div>
<div class=clr></div>
<div id=topartists>
<div class=thinbox>
<div>
<div>
<div>
<h5><a href="/topartists.html">Top Artists</a></h5>
<table cellpadding="1" cellspacing="2" width="100%" height="150">
<tr class=charts>
<td valign="top">
<a href="/rihanna_lyrics.html" title="Rihanna lyrics">Rihanna lyrics</a><br>
<a href="/kapone47_lyrics.html" title="Kapone47 lyrics">Kapone47 lyrics</a><br>
<a href="/2anormal_lyrics.html" title="2anormal lyrics">2anormal lyrics</a><br>
<a href="/dvbbs_and_borgeous_lyrics.html" title="DVBBS & Borgeous lyrics">DVBBS & Borgeous lyrics</a><br>
<a href="/ross_lynch,_maia_mitchell_and_teen_beach_movie_cast_lyrics.html" title="Ross Lynch, Maia Mitchell & Teen Beach Movie Cast lyrics">Ross Lynch, Maia Mitchell & Teen Beach Movie Cast lyrics</a><br>
<a href="/miley_cyrus_lyrics.html" title="Miley Cyrus lyrics">Miley Cyrus lyrics</a><br>
<a href="/mumford_and_sons_lyrics.html" title="Mumford & Sons lyrics">Mumford & Sons lyrics</a><br>
<a href="/nicki_minaj_lyrics.html" title="Nicki Minaj lyrics">Nicki Minaj lyrics</a><br>
<a href="/arctic_monkeys_lyrics.html" title="Arctic Monkeys lyrics">Arctic Monkeys lyrics</a><br>
<a href="/adele_lyrics.html" title="Adele lyrics">Adele lyrics</a><br>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div></div>
</div>
<div id=toplyrics>
<div class=thinbox>
<div>
<div>
<div>
<h5><a href="/toplyrics.html">Top Lyrics</a></h5>
<table cellpadding="1" cellspacing="2" width="564" height="150">
<tr class=charts>
<td valign="top">
Katy Perry - <a href="/roar_lyrics_katy_perry.html" title="Roar lyrics">Roar lyrics</a><br>
Avicii - <a href="/wake_me_up_lyrics_avicii.html" title="Wake Me Up lyrics">Wake Me Up lyrics</a><br>
Martin Garrix - <a href="/animals_lyrics_martin_garrix.html" title="Animals lyrics">Animals lyrics</a><br>
Romeo Santos - <a href="/propuesta_indecente_lyrics_romeo_santos.html" title="Propuesta Indecente lyrics">Propuesta Indecente lyrics</a><br>
Of Monsters And Men - <a href="/little_talks_lyrics_of_monsters_and_men_1.html" title="Little Talks lyrics">Little Talks lyrics</a><br>
Ed Sheeran - <a href="/lego_house_lyrics_ed_sheeran.html" title="Lego House lyrics">Lego House lyrics</a><br>
Fray (The) - <a href="/how_to_save_a_life_lyrics_fray_the.html" title="How To Save A Life lyrics">How To Save A Life lyrics</a><br>
Capital Cities - <a href="/safe_and_sound_lyrics_capital_cities.html" title="Safe and Sound lyrics">Safe and Sound lyrics</a><br>
Lulu and the Lampshades - <a href="/youre_gonna_miss_me_lyrics_lulu_and_the_lampshades.html" title="You're Gonna Miss Me lyrics">You're Gonna Miss Me lyrics</a><br>
DVBBS & Borgeous - <a href="/tsunami_lyrics_dvbbs_and_borgeous.html" title="Tsunami lyrics">Tsunami lyrics</a><br>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div></div>
</div>
</div>
<div id=leftcolumn2>
<div class=thinbox>
<div>
<div>
<div>
<h5>Main Menu</h5>
<a href="/contact.html">Contact Us</a><br />
<a href="/dancelyrics.html">Dance Lyrics</a>
<a href="/jinglebellslyrics.html" title="Jingle Bells Lyrics">Jingle Bells Lyrics</a><br />
<a href="/biographies.html">Biographies</a><br />
<a href="/links.html">Links</a><br />
<a href="/linkus.html">Link To Us</a><br />
<a href="/toadvertise.html">To Advertise</a><br />
<a href="/contact.html">Request Lyrics</a><br />
</div>
</div>
</div>
</div>
<div class=thinbox>
<div>
<div>
<div>
<h5>Play This Song</h5>
<!-- start snippet -->
<div class="boxcontent1"><!-- this line may not be needed-->
<div class="boxcontent2" style="height:45px;"> <!-- this line may not be
needed-->
<!-- edit this DIV below for positioning -->
<div style="position:relative;left:-41px;top:-35px;">
<script type="text/javascript" src="
http://cd02.static.jango.com/javascripts/promos/jangolib_3.js"></script>
<link rel=StyleSheet href="
http://cd02.static.jango.com/stylesheets/promo/jangoscroller_3b.css"
type="text/css">
<div class="scroller">
<div class="expandBtn"><a href="http://www.jango.com" target="_blank"
class="expandBtn"><img src="
http://cd02.static.jango.com/images/promo/playerCornerSpacer_1.gif"
border="0" width="10" height="10" alt="free music" /></a></div>
<div class="playerBG"><a href="http://www.jango.com/play/Lilly Wood & The Prick/Hey It's Ok"
target="_blank">
<img src="
http://cd02.static.jango.com/images/promo/playerLyrics160Black.gif"
border="0" alt="free music" /></a></div>
<div style="position:absolute;top:26px;left:18px;">
<marquee width="140" scrolldelay="150">
<a href="http://www.jango.com/play/Lilly Wood & The Prick/Hey It's Ok" class="playList">Lilly Wood & The Prick - Hey It's Ok</a>
</marquee>
</div>
</div>
<img src="http://p.jango.com/lyricsmania.gif"
style="width:1px;height:1px;" />
</div>
</div><!-- this line may not be needed-->
</div><!-- this line may not be needed-->
<div class="boxfooter"></div><!-- this line may not be needed-->
<!-- snippet end -->
<div style="text-align:center; margin-left:-20px;">
<script type="text/javascript">
GA_googleFillSlotWithSize("ca-pub-3687873374834629",
"LyricsMania_160x170_wrapper", 160, 170);
</script>
</div>
</div>
</div>
</div>
</div>
<div style='margin-bottom: 10px'>
<script type="text/javascript"><!--
e9 = new Object();
e9.size = "160x600,120x600";
e9.addBlockingCategories="Audio,Pop-under,Pop-up";
//--></script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/LyricsMania/ROS/tags.js"></script>
</div>
<div class=thinbox>
<div>
<div>
<div>
<h5>Partners</h5>
<a href="http://www.uplyrics.com/" target=_blank title="Lyrics">Lyrics</a><br>
<a href="http://www.parolesmania.com/paroles_lilly_wood_and_the_prick_57989.html" target=_blank title="Paroles Lilly Wood & The Prick">Paroles Lilly Wood & The Prick</a><br>
<a href="http://www.testimania.com/" target=_blank title="Testi Gratis">Testi Canzoni</a><br>
<a href="http://www.letrasmania.com/" target=_blank title="Letras de canciones">Letras De Canciones</a><br>
<a href="http://www.angolotesti.i/" target=_blank title="Testi Canzoni Gratis">Testi Di Canzoni</a><br>
<a href="http://www.ricettemania.it" target=_blank>Ricette</a><br>
<a href="http://www.musictory.com" title="Music Directory" target=_blank>Musictory</a><br>
</div>
</div>
</div>
</div>
<div></div>
</div>
<div class=clr></div></div>
<div class=clr></div></div>
<div id=whitebox_b>
<div id=whitebox_bl>
<div id=whitebox_br>
</div>
</div>
</div>
</div>
<div id=footer>
<div id=footer_l>
<div id=footer_r>
<div>LyricsMania.com - Copyright &#169; 2013 - All Rights Reserved<br /><a href="/privacy.php">Privacy Policy</a></div>
</div>
</div>
</div>
<div id="toolbar" style="bottom: -60px;">
<div id="toolbar-content">
<ul>
<li>
<img src="/pictures/thumbnails/73507.jpg">
<a href="/miranda_lambert_lyrics.html" onclick="javascript: pageTracker._trackPageview('/toolbar');">Miranda Lambert</a>
</li>
<li>
<img src="/pictures/thumbnails/1974.jpg">
<a href="/last_day_before_holiday_lyrics.html" onclick="javascript: pageTracker._trackPageview('/toolbar');">Last Day Before Holiday</a>
</li>
<li>
<img src="/pictures/thumbnails/69023.jpg">
<a href="/afrim_muqiqi_lyrics.html" onclick="javascript: pageTracker._trackPageview('/toolbar');">Afrim Muqiqi</a>
</li>
<li>
<img src="/pictures/thumbnails/91173.jpg">
<a href="/downset_lyrics.html" onclick="javascript: pageTracker._trackPageview('/toolbar');">Downset</a>
</li>
<li>
<img src="/pictures/thumbnails/74453.jpg">
<a href="/jamar_rogers_lyrics.html" onclick="javascript: pageTracker._trackPageview('/toolbar');">Jamar Rogers</a>
</li>
<div class="clear"></div>
</ul>
</div> <!-- toolbar-content -->
<div id="close"><a href="javascript:void(0);" onclick="toolbar('open-toolbar','toolbar')"><img src="/images/close-down.png"></a></div> <!-- close -->
</div> <!-- toolbar -->
<div id="open-toolbar" style="display:none; bottom: -60px;"><a href="javascript:void(0);" onclick="toolbar('toolbar','open-toolbar')"><img src="/images/open-up.png"></a></div>
<script>
setTimeout(function(){slide('toolbar')},2);
</script>
</div></div>
<div id="rect_ad_loader" style="display:none;">
<div class=thinbox>
<div>
<div>
<div>
<script type="text/javascript"><!--
e9 = new Object();
e9.size = "300x250";
e9.addBlockingCategories="Audio,Pop-under,Pop-up";
//--></script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/LyricsMania/ROS/tags.js"></script>
<script type="text/javascript">
document.getElementById("rect_ad").innerHTML = document.getElementById("rect_ad_loader").innerHTML
</script></div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,613 @@
<!DOCTYPE html>
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>The Beatles - Lady Madonna Lyrics</title>
<meta name=description content="The Beatles Lady Madonna Lyrics. Lady Madonna lyrics performed by The Beatles: Lady Madonna, children at your feet.
Wonder how you manage to make ends meet.
Who finds the money? When you pay the rent?
Did you think that money was heaven sent?
">
<meta name=keywords content="lady madonna,the beatles,lyrics,words,song">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<meta http-equiv="expires" content="0" />
<meta name="language" content="en" />
<meta property="og:title" content="The Beatles - Lady Madonna Lyrics"/>
<meta property="og:type" content="song"/>
<meta property="og:url" content="http://www.lyricsmania.com/lady_madonna_lyrics_the_beatles.html"/>
<meta property="og:site_name" content="www.lyricsmania.com"/>
<meta property="og:description" content="The Beatles Lady Madonna Lyrics. Lady Madonna lyrics performed by The Beatles: Lady Madonna, children at your feet.
Wonder how you manage to make ends meet.
Who finds the money? When you pay the rent?
Did you think that money was heaven sent?
">
<meta property="og:language" content="en"/>
<meta property="fb:admins" content="100001599431689" />
<meta name="classification" content="The Beatles lyrics" />
<script type="text/javascript" src="http://partner.googleadservices.com/gampad/google_service.js">
</script>
<script type="text/javascript">
GS_googleAddAdSenseService("ca-pub-3687873374834629");
GS_googleEnableAllServices();
</script>
<script type="text/javascript">
GA_googleUseIframeRendering();
GA_googleAddAttr("j_title", "Lady Madonna");
GA_googleAddAttr("j_artist", "The Beatles");
</script>
<link rel="image_src" href="/files/toplogo4.jpg" />
<link href="/css/style.css?version=2.2" type=text/css rel=stylesheet>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="/css/mobile.css?version=1.3" media="only screen and (max-width: 600px)" />
<link rel="canonical" href="http://www.lyricsmania.com/lady_madonna_lyrics_the_beatles.html">
<link rel="alternate" hreflang="es" href="http://www.letrasmania.com/" />
<link rel="alternate" hreflang="it" href="http://www.testimania.com/" />
<link rel="alternate" hreflang="fr" href="http://www.parolesmania.com/" />
<link rel="alternate" hreflang="de" href="http://www.songtextemania.com/" />
<link href="http://www.lyricsmania.com/xml/last100album.xml" rel="alternate" type="application/rss+xml" title="Last 100 Albums" />
<link href="http://www.lyricsmania.com/xml/last100artists.xml" rel="alternate" type="application/rss+xml" title="Last 100 Artists" />
<link href="http://www.lyricsmania.com/xml/last100lyrics.xml" rel="alternate" type="application/rss+xml" title="Last 150 Lyrics" />
<script type="text/javascript" src="/js/lm_js.js"></script>
<script type="text/javascript" src="/js/functions.js"></script>
<script language="javascript" type="text/javascript" src="/copy.js"></script>
<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
{lang: 'en'}
</script>
<meta name="google" value="notranslate">
<script type="text/javascript">
window.___gcfg = {lang: 'en'};
(function()
{var po = document.createElement("script");
po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(po, s);
})();</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-435431-1']);
_gaq.push(['_setDomainName', 'lyricsmania.com']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<script>
cf_page_artist = "The Beatles";
cf_page_song = "Lady Madonna";
cf_page_genre = "";
cf_adunit_id = "39381134";
cf_flex = true;
</script>
<script src="//srv.clickfuse.com/showads/showad.php"></script>
<script type="text/javascript">
function toolbar(id_el,id_eldue) {
el = document.getElementById(id_el);
eldue = document.getElementById(id_eldue);
_display = (el.style.display);
if (_display == "none") {
eldue.style.bottom = "-60px";
eldue.style.display = "none";
el.style.display = "block";
setTimeout(function(){slide(el)},2);
}
else {
el.style.display = "none";
eldue.style.display = "block";
}
}
function slide(id_el) {
if(!id_el.id) {
el = document.getElementById(id_el);
}
_bottom = parseInt(el.style.bottom);
if (_bottom < '0') {
el.style.bottom = (_bottom+2)+"px";
setTimeout(function(){slide(id_el)},5);
}
}
</script>
<script type='text/javascript'>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
(function() {
var gads = document.createElement('script');
gads.async = true;
gads.type = 'text/javascript';
var useSSL = 'https:' == document.location.protocol;
gads.src = (useSSL ? 'https:' : 'http:') +
'//www.googletagservices.com/tag/js/gpt.js';
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(gads, node);
})();
</script>
<script type='text/javascript'>
googletag.cmd.push(function() {
googletag.defineSlot('/11720687/160x600_Lyrics_Mania', [160, 600], 'div-gpt-ad-1382118547478-0').addService(googletag.pubads());
googletag.defineSlot('/11720687/300x250_Lyrics_Mania', [300, 250], 'div-gpt-ad-1383259478593-0').addService(googletag.pubads());
googletag.defineSlot('/11720687/728x90_Lyrics_Mania', [728, 90], 'div-gpt-ad-1383258129199-0').addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>
<body>
<h1>Lady Madonna Lyrics</h1>
<div id="container">
<div id="header">
<div class="logo"><a href="/" title="Lyricsmania"><img src="/css/lyricsmania-460x154.png" border="0"></a></div>
<div class="leaderboard mobile-display"><!-- 728x90_Lyrics_Mania -->
<script type="text/javascript"><!--
e9 = new Object();
e9.size = "728x90,468x60";
e9.addBlockingCategories="Audio,Pop-under,Pop-up";
//--></script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/LyricsMania/ROS/tags.js"></script>
</div>
</div> <!-- header -->
<div id="menu" class="mobile-display">
<ul>
<li><a href="/">Lyricsmania</a></li>
<li><a href="/soundtrackslyrics.html">Soundtrack Lyrics</a></li>
<li><a href="/topartists.html">Top 100 Artists</a></li>
<li><a href="/toplyrics.html">Top 100 Lyrics</a></li>
<li><a href="/add.html">Submit Lyrics</a></li>
<li style="margin-left: 15px; border: none;">
<form class="logina" action="http://my.lyricsmania.com/login.php?destpage=/lady_madonna_lyrics_the_beatles.html">
<input class="formino" type="text" name="username" size="9" maxlength="18" value="Username" onFocus="if(this.value == 'Username') {this.value = '';}" onBlur="if (this.value == '') {this.value = 'Username';}" />
<input class="formino" type="password" name="password" size="9" maxlength="18" value="Password" onFocus="if(this.value == 'Password') {this.value = '';}" onBlur="if (this.value == '') {this.value = 'Password';}" />
<input class="loginb" type="submit" value="Login"> or
</form>
</li>
<li style="border: none;"><a href="http://my.lyricsmania.com/signup.html" style="color: yellow; margin-top: 1px;">Signup</a> </li>
</ul>
</div> <!-- menu -->
<div id="main">
<div id="content">
<div id="search">
<form action="/searchnew.php">
<input type="text" name="k" onclick="if (this.value == 'Find Artist and/or Lyrics') this.value=''" value="Find Artist and/or Lyrics" onblur="if(this.value == '') this.value='Find Artist and/or Lyrics'" value="">
<span class="search-image"><input type="image" src="/sbut.png" value="Search!"></span>
</form>
<div class="clear spacer-10"></div>
<div class="search-nav">
Browse:
<a href="/lyrics/num.html">0-9</a>
<a href="/lyrics/A.html">A</a>
<a href="/lyrics/B.html">B</a>
<a href="/lyrics/C.html">C</a>
<a href="/lyrics/D.html">D</a>
<a href="/lyrics/E.html">E</a>
<a href="/lyrics/F.html">F</a>
<a href="/lyrics/G.html">G</a>
<a href="/lyrics/H.html">H</a>
<a href="/lyrics/I.html">I</a>
<a href="/lyrics/J.html">J</a>
<a href="/lyrics/K.html">K</a>
<a href="/lyrics/L.html">L</a>
<a href="/lyrics/M.html">M</a>
<a href="/lyrics/N.html">N</a>
<a href="/lyrics/O.html">O</a>
<a href="/lyrics/P.html">P</a>
<a href="/lyrics/Q.html">Q</a>
<a href="/lyrics/R.html">R</a>
<a href="/lyrics/S.html">S</a>
<a href="/lyrics/T.html">T</a>
<a href="/lyrics/U.html">U</a>
<a href="/lyrics/V.html">V</a>
<a href="/lyrics/W.html">W</a>
<a href="/lyrics/X.html">X</a>
<a href="/lyrics/Y.html">Y</a>
<a href="/lyrics/Z.html">Z</a>
</div> <!-- search-nav -->
</div> <!-- search -->
<div class="clear spacer-20"></div>
<div class="lyrics-nav-menu">
<ul>
<li><a href="/the_beatles_lyrics.html" title="The Beatles lyrics">The Beatles</a></li>
<li class="active">Lady Madonna</li>
<li><a href="http://www.musictory.com/music/The+Beatles/Biography" target="_blank" onclick="javascript: pageTracker._trackPageview('/musictory-biography-testo');">Biography</a></li>
<li><a href="http://www.musictory.com/music/The+Beatles/Pictures" target="_blank" onclick="javascript: pageTracker._trackPageview('/musictory-pictures-testo');">Pictures</a></li>
</ul>
<div class="clear"></div>
</div> <!-- lyrics-nav-menu -->
<div class="lyrics-nav">
<div class="col-left width-400">
<img src="/css/artist.png" class="artist">
<hgroup>
<h2>Lady Madonna lyrics</h2>
<h3>The Beatles</h3>
</hgroup>
<ul class="function-nav">
<li><img src="/files/correct.png"><a href="/correct.php?id=1424308" rel="nofollow">Correct</a></li>
<li><img src="/files/print.png"><a href="/print/1424308.html" target="_blank" rel="nofollow">Print</a></li>
<li><img src="/images/pencil2.png"><a href="#commentlyrics" rel="nofollow">Comment</a></li>
</ul>
</div> <!-- col-left -->
<div class="col-right width-222">
<ul>
<li><iframe src="http://www.facebook.com/plugins/like.php?href=http://www.lyricsmania.com/lady_madonna_lyrics_the_beatles.html&amp;send=false&amp;layout=box_count&amp;width=100&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:85px; height:65px;" allowTransparency="true"></iframe></li>
<li><a href="http://twitter.com/share" class="twitter-share-button" data-count="vertical" data-via="lyricsmaniacom">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></li>
<li><g:plusone size="tall" href="http://www.lyricsmania.com/lady_madonna_lyrics_the_beatles.html"></g:plusone></li>
</ul>
</div> <!-- col-right -->
<div class="clear spacer-10"></div>
<div id="rate-song">
<div class="col-left width-400">
<h5>Rate this song:</h5>
<form method="post" name="addme" action="http://my.lyricsmania.com/vote.html">
<input type="hidden" name="id_artista" value="115896">
<input type="hidden" name="id_testo" value="1424308">
<input type="radio" name="voto" value="1" onclick="this.form.submit()" />1
<input type="radio" name="voto" value="2" onclick="this.form.submit()" />2
<input type="radio" name="voto" value="3" onclick="this.form.submit()" />3
<input type="radio" name="voto" value="4" onclick="this.form.submit()" />4
<input type="radio" name="voto" value="5" onclick="this.form.submit()" />5
</form>
<div class="notes">
No votes yet, be the first!
</div> <!-- .notes -->
</div> <!-- #rate-song -->
</div> <!-- col-left -->
<div class="col-right width-222" id="favorites" style="text-align: left;">
<a href="http://my.lyricsmania.com/playlist/add/.html"><img src="/files/addfavorites.png" border="0"></a> <a href="http://my.lyricsmania.com/playlist/add/1424308.html">Add to my playlist</a>
</div> <!-- col-right -->
<div class="clear"></div>
</div> <!-- lyrics-nav -->
<div class="clear spacer-20"></div>
<div class="lyrics">
<div class="col-left">
<script>
/* LyricsMania.com - Above Lyrics */
(function() {
var opts = {
artist: "The Beatles",
song: "Lady Madonna",
genre: "",
adunit_id: 39382211,
div_id: "cf_async_" + Math.floor((Math.random() * 999999999)),
hostname: "srv.tonefuse.com"
};
document.write('<div id="'+opts.div_id+'"></div>');var
c=function(){cf.showAsyncAd(opts)};if(window.cf)c();else{cf_async=!0;var
r=document.createElement("script"),s=document.getElementsByTagName("script")[0];r.async=!0;r.src="//"+opts.hostname+"/showads/showad.js";r.readyState?r.onreadystatechange=function(){if("loaded"==r.readyState||"complete"==r.readyState)r.onreadystatechange=null,c()}:r.onload=c;s.parentNode.insertBefore(r,s)};
})();
</script>
<div class="clear spacer-10"></div>
<div class="lyrics-body" oncopy="copy('');">
<div id="video-musictory">
<h5 style="font-size: 13px;">Lady Madonna Video:</h5>
<a href="http://www.musictory.com/music/The+Beatles/Lady+Madonna" target="_blank" class="a-video" onclick="javascript: pageTracker._trackPageview('/videomusictory');"><img src="http://i.ytimg.com/vi/VfthrizXKOM/0.jpg" border="0" class="thumb-video"><img src="/images/play2.png" class="play-video"></a>
</div>
<strong>Lyrics to Lady Madonna</strong>
Lady Madonna, children at your feet.<br />
Wonder how you manage to make ends meet.<br />
Who finds the money? When you pay the rent?<br />
Did you think that money was heaven sent?<br />
<br />
Friday night arrives without a suitcase.<br />
Sunday morning creep in like a nun.<br />
Monday's child has learned to tie his bootlace.<br />
See how they run.<br />
<br />
Lady Madonna, baby at your breast.<br />
Wonder how you manage to feed the rest.<br />
<br />
See how they run.<br />
Lady Madonna, lying on the bed,<br />
Listen to the music playing in your head.<br />
<br />
Tuesday afternoon is never ending.<br />
Wednesday morning papers didn't come.<br />
Thursday night you stockings needed mending.<br />
See how they run.<br />
<br />
Lady Madonna, children at your feet.<br />
Wonder how you manage to make ends meet. </div> <!-- lyrics-body -->
<div class="clear spacer-10"></div>
&#91; These are <a href="lady_madonna_lyrics_the_beatles.html" title="Lady Madonna Lyrics">Lady Madonna Lyrics</a> on http://www.lyricsmania.com/ &#93;
<div class="clear spacer-20"></div>
<script>
/* LyricsMania.com - Below Lyrics */
(function() {
var opts = {
artist: "The Beatles",
song: "Lady Madonna",
genre: "",
adunit_id: 39382212,
div_id: "cf_async_" + Math.floor((Math.random() * 999999999)),
hostname: "srv.tonefuse.com"
};
document.write('<div id="'+opts.div_id+'"></div>');var
c=function(){cf.showAsyncAd(opts)};if(window.cf)c();else{cf_async=!0;var
r=document.createElement("script"),s=document.getElementsByTagName("script")[0];r.async=!0;r.src="//"+opts.hostname+"/showads/showad.js";r.readyState?r.onreadystatechange=function(){if("loaded"==r.readyState||"complete"==r.readyState)r.onreadystatechange=null,c()}:r.onload=c;s.parentNode.insertBefore(r,s)};
})();
</script>
<div class="clear spacer-20"></div>
<h5>Other The Beatles Lyrics</h5>
<ul class="altri-testi">
<li><a href="/let_it_be_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Let It Be lyrics</a></li>
<li><a href="/come_together_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Come Together lyrics</a></li>
<li><a href="/all_you_need_is_love_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">All You Need Is Love lyrics</a></li>
<li><a href="/hey_jude_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Hey Jude lyrics</a></li>
<li><a href="/yesterday_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Yesterday lyrics</a></li>
</ul><ul class="altri-testi"> <li><a href="/something_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Something lyrics</a></li>
<li><a href="/eleanor_rigby_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Eleanor Rigby lyrics</a></li>
<li><a href="/get_back_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Get Back lyrics</a></li>
<li><a href="/yellow_submarine_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Yellow Submarine lyrics</a></li>
<li><a href="/help!_lyrics_the_beatles.html" onclick="javascript: pageTracker._trackPageview('/linkartista-testo');">Help! lyrics</a></li>
</ul>
<div class="clear spacer-20"></div>
<div class="comment-lyrics">
<h5><a name="commentlyrics">Comments to these lyrics</a></h5>
<a href="javascript:void(0);" onclick="popolaDiv('comment_post','leave_comment')" id="leave_comment">Leave a Comment</a><br />
<div id="comment_post" style="display: none;">
<form method=post action="http://my.lyricsmania.com/login.php?destpage=/comments/add.html" id="add_comment_form" name="add_comment_form" onSubmit="validateForm(add_comment_form.comment)">
<input type="hidden" name="id_testo" value="1424308">
<textarea type=text maxlenght=50 rows="5" cols="33" wrap="virtual" name="comment" onKeyDown="limitText(this.form.comment,this.form.countdown,500);"
onKeyUp="limitText(this.form.comment,this.form.countdown,500);"></textarea>
<div class="clear spacer-10"></div>
<font size="1">(Maximum characters: 500) | You have <input readonly type="text" name="countdown" size="3" value="500"> characters left.</font>
<div class="clear spacer-10"></div>
Verification (Enter the text in the image): <input id="verification" type="text" name="verification">
<div class="clear spacer-15"></div>
<img border="0" src="/captcha.php">
<input type="submit" name="add_comment" value="Add Comment" id="submit_comment"> </form>
<div class="clear"></div>
</div> <!-- #comment_post -->
No comments to these lyrics yet, be the first!
</div> <!-- #comments -->
<div class="clear"></div>
</div> <!-- col-left -->
<div class="col-right">
<div class="clear spacer-20"></div>
<script type="text/javascript"><!--
e9 = new Object();
e9.size = "160x600,120x600";
e9.addBlockingCategories="Audio,Pop-under,Pop-up";
//--></script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/LyricsMania/ROS/tags.js"></script>
<!-- 160x600_Lyrics_Mania -->
</div> <!-- col-right -->
<div class="clear"></div>
</div> <!-- lyrics -->
<div class="clear spacer-20"></div>
</div> <!-- content -->
<div id="navigation">
<div class="clear spacer-20"></div>
<script type="text/javascript"><!--
e9 = new Object();
e9.size = "300x250";
e9.addBlockingCategories="Audio,Pop-under,Pop-up";
//--></script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/LyricsMania/ROS/tags.js"></script>
<!-- 300x250_Lyrics_Mania -->
<div class="clear spacer-20"></div>
<div id="fb-root"></div>
<script>
/*
window.fbAsyncInit = function() {
FB.init({
appId : '137256903140676',
channelUrl : '//www.facebook.com/pages/Lyrics-Mania/144174245625143',
status : true,
xfbml : true
});
}
;*/
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<iframe src="http://www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Fpages%2FLyrics-Mania%2F144174245625143&amp;width=292&amp;colorscheme=light&amp;show_faces=true&amp;stream=false&amp;header=false&amp;height=258" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:292px; height:258px;" allowTransparency="true"></iframe>
<div class="g-plus" data-href="https://plus.google.com/112654762505809752225?rel=publisher" data-width="300" data-height="69" data-theme="light"></div>
<div class="clear spacer-20"></div>
<div id="navigation-last">
<h5 id="h5-lyrics" style="width: 145px; border: none;"><a href="javascript:void(0);" onclick="changeNav('last-artists','last-lyrics','h5-artists','h5-lyrics')" style="color: #000;">Last Added Lyrics</a></h5>
<ul id="last-lyrics">
<li><a href="/sgt_peppers_lonely_hearts_club_ban_lyrics_the_beatles.html">Sgt. Peppers lonely hearts club ban lyrics</a></li>
<li><a href="/ob-la-di_ob-la-da_lyrics_the_beatles.html">Ob-La-Di Ob-La-Da lyrics</a></li>
<li><a href="/imagine_lyrics_the_beatles.html">Imagine lyrics</a></li>
<li><a href="/i_wanna_hold_your_hand_lyrics_the_beatles.html">I wanna hold your hand lyrics</a></li>
<li><a href="/helter_skelter_lyrics_the_beatles.html">Helter Skelter lyrics</a></li>
<li><a href="/hello,_goodbey_lyrics_the_beatles.html">Hello, goodbey lyrics</a></li>
<li><a href="/and_she_sweet_lyrics_the_beatles.html">and she sweet lyrics</a></li>
<li><a href="/a_hard_days_night_lyrics_the_beatles.html">A hard days night lyrics</a></li>
<li><a href="/i_will_lyrics_the_beatles.html">I Will lyrics</a></li>
<li><a href="/i_will_lyrics_the_beatles.html">I Will lyrics</a></li>
<li><a href="/i_will_lyrics_the_beatles.html">I Will lyrics</a></li>
<li><a href="/your_mother_should_know_lyrics_the_beatles.html">Your Mother Should Know lyrics</a></li>
<li><a href="/youve_got_to_hide_your_love_lyrics_the_beatles.html">You've Got To Hide Your Love lyrics</a></li>
<li><a href="/youre_going_to_lose_that_girl_lyrics_the_beatles.html">You're Going To Lose That Girl lyrics</a></li>
<li><a href="/you_wont_see_me_lyrics_the_beatles.html">You Won't See Me lyrics</a></li>
</ul>
<div class="clear spacer-20"></div>
<h5 id="h5-artists" style="width: 140px; left: 150px; background: #f9f9f9; padding-left: 10px;"><a href="javascript:void(0);" onclick="changeNav('last-lyrics','last-artists','h5-lyrics','h5-artists')">Last Artists</a></h5>
<ul id="last-artists" style="visibility: hidden; position: absolute;">
<li><a href="/cali_flow_latino_lyrics.html" title="Cali Flow Latino lyrics">Cali Flow Latino lyrics</a></li>
<li><a href="/patty_tamares_lyrics.html" title="Patty Tamares lyrics">Patty Tamares lyrics</a></li>
<li><a href="/yves_v_and_regi_lyrics.html" title="Yves V & Regi lyrics">Yves V & Regi lyrics</a></li>
<li><a href="/parix_lyrics.html" title="Parix lyrics">Parix lyrics</a></li>
<li><a href="/nicholas_krgovich_lyrics.html" title="Nicholas Krgovich lyrics">Nicholas Krgovich lyrics</a></li>
<li><a href="/scott_walker_sunn_o_lyrics.html" title="Scott Walker + Sunn O))) lyrics">Scott Walker + Sunn O))) lyrics</a></li>
<li><a href="/uwe_kaa_lyrics.html" title="Uwe Kaa lyrics">Uwe Kaa lyrics</a></li>
<li><a href="/circus_neon_lyrics.html" title="Circus Neon lyrics">Circus Neon lyrics</a></li>
<li><a href="/sebastian_yatra_lyrics.html" title="Sebastian Yatra lyrics">Sebastian Yatra lyrics</a></li>
<li><a href="/alday_arts_lyrics.html" title="Alday Arts lyrics">Alday Arts lyrics</a></li>
<li><a href="/duryea_hozay_lyrics.html" title="Duryea Hozay lyrics">Duryea Hozay lyrics</a></li>
<li><a href="/necrotted_lyrics.html" title="Necrotted lyrics">Necrotted lyrics</a></li>
<li><a href="/melloy_lyrics.html" title="Melloy lyrics">Melloy lyrics</a></li>
<li><a href="/tuch_lyrics.html" title="Tuch. lyrics">Tuch. lyrics</a></li>
<li><a href="/sylas_lyrics.html" title="Sylas lyrics">Sylas lyrics</a></li>
</ul>
<div class="clear"></div>
</div> <!-- navigation-last -->
<div class="clear spacer-50"></div>
<div id="navigation-top">
<h5 id="h5-top-lyrics" style="border: none;"><a href="javascript:void(0);" onclick="changeNav('last-top-artists','last-top-lyrics','h5-top-artists','h5-top-lyrics')" style="color: #000;">Top lyrics</a></h5>
<ul id="last-top-lyrics">
<li>Lilly Wood & The Prick - <a href="/prayer_in_c_lyrics_lilly_wood_and_the_prick.html" title="Prayer In C lyrics">Prayer In C lyrics</a></li>
<li>Enrique Iglesias - <a href="/bailando_english_version_lyrics_enrique_iglesias.html" title="Bailando (English Version) lyrics">Bailando (English Version) lyrics</a></li>
<li>Teenage Mutant Ninja Turtles - <a href="/teenage_mutant_ninja_turtles_theme_song_lyrics_teenage_mutant_ninja_turtles.html" title="Teenage Mutant Ninja Turtles Theme Song lyrics">Teenage Mutant Ninja Turtles Theme Song lyrics</a></li>
<li>Lilly Wood & The Prick & Robin Schulz - <a href="/prayer_in_c_lyrics_lilly_wood_and_the_prick_and_robin_schulz.html" title="Prayer In C lyrics">Prayer In C lyrics</a></li>
<li>One Direction - <a href="/steal_my_girl_lyrics_one_direction.html" title="Steal My Girl lyrics">Steal My Girl lyrics</a></li>
<li>Milky Chance - <a href="/stolen_dance_lyrics_milky_chance.html" title="Stolen Dance lyrics">Stolen Dance lyrics</a></li>
<li>Kadebostany - <a href="/castle_in_the_snow_lyrics_kadebostany.html" title="Castle In The Snow lyrics">Castle In The Snow lyrics</a></li>
<li>Mr. Probz - <a href="/waves_lyrics_mr_probz.html" title="Waves lyrics">Waves lyrics</a></li>
<li>Frozen [OST] - <a href="/let_it_go_lyrics_frozen_[ost].html" title="Let It Go lyrics">Let It Go lyrics</a></li>
<li>Itch - <a href="/another_man_lyrics_itch.html" title="Another Man lyrics">Another Man lyrics</a></li>
<li>Of Monsters And Men - <a href="/little_talks_lyrics_of_monsters_and_men.html" title="Little Talks lyrics">Little Talks lyrics</a></li>
<li>Roots (The) - <a href="/here_i_come_lyrics_roots_the.html" title="Here I Come lyrics">Here I Come lyrics</a></li>
<li>Roots (The) - <a href="/cant_stop_this_lyrics_roots_the.html" title="Can't Stop This lyrics">Can't Stop This lyrics</a></li>
<li>Roots (The) - <a href="/kool_on_lyrics_roots_the.html" title="Kool On lyrics">Kool On lyrics</a></li>
<li>Roots (The) - <a href="/baby_lyrics_roots_the.html" title="Baby lyrics">Baby lyrics</a></li>
<span><a href="/toplyrics.html">view all</a></span>
</ul>
<div class="clear spacer-20"></div>
<h5 id="h5-top-artists" style="width: 120px; left: 160px; background: #f9f9f9; padding-left: 20px;"><a href="javascript:void(0);" onclick="changeNav('last-top-lyrics','last-top-artists','h5-top-lyrics','h5-top-artists')">Top Artists</a></h5>
<ul id="last-top-artists" style="visibility: hidden; position: absolute;">
<li><a href="/frozen_[ost]_lyrics.html" title="Frozen [OST] lyrics">Frozen [OST] lyrics</a></li>
<li><a href="/kendji_girac_lyrics.html" title="Kendji Girac lyrics">Kendji Girac lyrics</a></li>
<li><a href="/if_then:_a_new_musical_lyrics.html" title="If/Then: A New Musical lyrics">If/Then: A New Musical lyrics</a></li>
<li><a href="/catfish_and_the_bottlemen_lyrics.html" title="Catfish And The Bottlemen lyrics">Catfish And The Bottlemen lyrics</a></li>
<li><a href="/5_seconds_of_summer_lyrics.html" title="5 Seconds Of Summer lyrics">5 Seconds Of Summer lyrics</a></li>
<li><a href="/high_school_musical_3_lyrics.html" title="High School Musical 3 lyrics">High School Musical 3 lyrics</a></li>
<li><a href="/mumford_and_sons_lyrics.html" title="Mumford & Sons lyrics">Mumford & Sons lyrics</a></li>
<li><a href="/broadway_musicals_lyrics.html" title="Broadway Musicals lyrics">Broadway Musicals lyrics</a></li>
<li><a href="/chris_brown_lyrics.html" title="Chris Brown lyrics">Chris Brown lyrics</a></li>
<li><a href="/perfume_genius_lyrics.html" title="Perfume Genius lyrics">Perfume Genius lyrics</a></li>
<li><a href="/kraftklub_lyrics.html" title="Kraftklub lyrics">Kraftklub lyrics</a></li>
<li><a href="/alt-j_lyrics.html" title="Alt-J lyrics">Alt-J lyrics</a></li>
<li><a href="/sufjan_stevens_lyrics.html" title="Sufjan Stevens lyrics">Sufjan Stevens lyrics</a></li>
<li><a href="/u2_lyrics.html" title="U2 lyrics">U2 lyrics</a></li>
<li><a href="/edith_piaf_lyrics.html" title="Edith Piaf lyrics">Edith Piaf lyrics</a></li>
<span><a href="/topartists.html">view all</a></span>
</ul>
<div class="clear"></div>
</div> <!-- navigation-top -->
<div class="clear spacer-20"></div>
</div> <!-- navigation -->
<div class="clear"></div>
</div> <!-- main -->
<script>
heightAll('main','navigation','content');
</script>
<div id="footer">
<div class="footer-partners">
<ul>
<li><a href="http://www.lyricsmania.com/contact.html">Contact us</a></li>
<li><a href="http://www.lyricsmania.com/links.html">Links</a></li>
<li><a href="http://www.lyricsmania.com/linkus.html">Links Us</a></li>
<li><a href="http://www.lyricsmania.com/toadvertise.html">To Advertise</a></li>
</ul>
</div> <!-- footer-partners -->
<div class="footer-nav">
<ul>
<li><a href="http://www.lyricsmania.com/dancelyrics.html">Dance Lyrics</a></li>
<li><a href="http://www.lyricsmania.com/jinglebellslyrics.html">Jingle Bells Lyrics</a></li>
<li><a href="http://www.uplyrics.com/" target="_blank" title="Lyrics">Up Lyrics</a></li>
<li><a href="http://www.stlyrics.com" target="_blank" rel="nofollow">ST Lyrics</a></li>
<li><a href="http://www.parolesmania.com/paroles_the_beatles_115896.html" target=_blank title="Paroles The Beatles">Paroles The Beatles</a></li>
</ul>
</div> <!-- footer-nav -->
<div class="footer-tool">
<ul>
<li><a href="https://www.facebook.com/pages/Lyrics-Mania/144174245625143">Facebook</a></li>
<li><a href="https://plus.google.com/112654762505809752225/posts">Google Plus</a></li>
<div class="clear"></div>
</ul>
</div> <!-- footer-tool -->
<div class="footer-network">
<h5>Our Network</h5>
<ul>
<li><a href="http://www.parolesmania.com"><span>Paroles De Chanson</span><img src="/css/parolesmania.png"></a></li>
<li><a href="http://www.songtextemania.com"><span>Songtextemania</span><img src="/css/songtextemania.png"></a></li>
<li><a href="http://www.letrasmania.com"><span>Letras De Canciones</span><img src="/css/letrasmania.png"></a></li>
<div class="clear"></div>
</ul>
</div> <!-- footer-network -->
<div class="clear"></div>
<div class="footer-bottom">
<a href="/" class="mobile-display"><img src="/css/lyricsmania-thumb.png"></a>
<span>LyricsMania.com - Copyright &#169; 2014 - All Rights Reserved <a href="/privacy.php">Privacy Policy</a></span>
</div> <!-- footer-bottom -->
<div class="clear"></div>
</div> <!-- footer -->
<div class="clear"></div>
</div> <!-- container -->
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,708 @@
<!DOCTYPE HTML>
<html prefix="og: http://ogp.me/ns#" lang='en-US' itemscope itemtype="http://schema.org/WebPage">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta property="og:title" content="Richie Havens &amp;mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens" />
<meta property="og:image" content="" />
<meta property="og:description" content="Lady Madonna lyrics by Richie Havens from album 20th Century Masters - The Millennium Collection: The Best Of Richie Havens. Lady Madonna, children at your feet Wonder how you manage to make ends meet Who finds the money" />
<meta property="og:url" content="http://www.stlyrics.com/songs/r/richiehavens48961/ladymadonna2069109.html" />
<meta property="fb:app_id" content="133000596876438" />
<meta property="og:type" content="website" />
<link rel="stylesheet" type="text/css" href="/assets/320fe20a/mprint.css" media="print" />
<style type="text/css">
/*<![CDATA[*/
/*!
* Bootstrap v2.3.2
*
* Copyright 2013 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}
.clearfix:after{clear:both;}
.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
audio:not([controls]){display:none;}
html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
a:hover,a:active{outline:0;}
sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
sup{top:-0.5em;}
sub{bottom:-0.25em;}
img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}
#map_canvas img,.google-maps img{max-width:none;}
button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
button,input{*overflow:visible;line-height:normal;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}
label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer;}
input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;}
input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
textarea{overflow:auto;vertical-align:top;}
@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important;} a,a:visited{text-decoration:underline;} a[href]:after{content:" (" attr(href) ")";} abbr[title]:after{content:" (" attr(title) ")";} .ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:"";} pre,blockquote{border:1px solid #999;page-break-inside:avoid;} thead{display:table-header-group;} tr,img{page-break-inside:avoid;} img{max-width:100% !important;} @page {margin:0.5cm;}p,h2,h3{orphans:3;widows:3;} h2,h3{page-break-after:avoid;}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333333;background-color:#ffffff;}
a{color:#0088cc;text-decoration:none;}
a:hover,a:focus{color:#005580;text-decoration:underline;}
.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);}
.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px;}
.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;}
.row:after{clear:both;}
[class*="span"]{float:left;min-height:1px;margin-left:20px;}
.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1000px;}
.span12{width:1000px;}
.span11{width:915px;}
.span10{width:830px;}
.span9{width:745px;}
.span8{width:660px;}
.span7{width:575px;}
.span6{width:490px;}
.span5{width:405px;}
.span4{width:320px;}
.span3{width:235px;}
.span2{width:150px;}
.span1{width:65px;}
.offset12{margin-left:1040px;}
.offset11{margin-left:955px;}
.offset10{margin-left:870px;}
.offset9{margin-left:785px;}
.offset8{margin-left:700px;}
.offset7{margin-left:615px;}
.offset6{margin-left:530px;}
.offset5{margin-left:445px;}
.offset4{margin-left:360px;}
.offset3{margin-left:275px;}
.offset2{margin-left:190px;}
.offset1{margin-left:105px;}
.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
.row-fluid:after{clear:both;}
.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2%;*margin-left:1.95%;}
.row-fluid [class*="span"]:first-child{margin-left:0;}
.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2%;}
.row-fluid .span12{width:100%;*width:99.95%;}
.row-fluid .span11{width:91.5%;*width:91.45%;}
.row-fluid .span10{width:83%;*width:82.95%;}
.row-fluid .span9{width:74.5%;*width:74.45%;}
.row-fluid .span8{width:66%;*width:65.95%;}
.row-fluid .span7{width:57.5%;*width:57.45%;}
.row-fluid .span6{width:49%;*width:48.95%;}
.row-fluid .span5{width:40.5%;*width:40.45%;}
.row-fluid .span4{width:32%;*width:31.95%;}
.row-fluid .span3{width:23.5%;*width:23.45%;}
.row-fluid .span2{width:15%;*width:14.95%;}
.row-fluid .span1{width:6.5%;*width:6.45%;}
.row-fluid .offset12{margin-left:104%;*margin-left:103.9%;}
.row-fluid .offset12:first-child{margin-left:102%;*margin-left:101.9%;}
.row-fluid .offset11{margin-left:95.5%;*margin-left:95.4%;}
.row-fluid .offset11:first-child{margin-left:93.5%;*margin-left:93.4%;}
.row-fluid .offset10{margin-left:87%;*margin-left:86.9%;}
.row-fluid .offset10:first-child{margin-left:85%;*margin-left:84.9%;}
.row-fluid .offset9{margin-left:78.5%;*margin-left:78.4%;}
.row-fluid .offset9:first-child{margin-left:76.5%;*margin-left:76.4%;}
.row-fluid .offset8{margin-left:70%;*margin-left:69.9%;}
.row-fluid .offset8:first-child{margin-left:68%;*margin-left:67.9%;}
.row-fluid .offset7{margin-left:61.5%;*margin-left:61.400000000000006%;}
.row-fluid .offset7:first-child{margin-left:59.5%;*margin-left:59.400000000000006%;}
.row-fluid .offset6{margin-left:53%;*margin-left:52.900000000000006%;}
.row-fluid .offset6:first-child{margin-left:51%;*margin-left:50.900000000000006%;}
.row-fluid .offset5{margin-left:44.5%;*margin-left:44.400000000000006%;}
.row-fluid .offset5:first-child{margin-left:42.5%;*margin-left:42.400000000000006%;}
.row-fluid .offset4{margin-left:36%;*margin-left:35.900000000000006%;}
.row-fluid .offset4:first-child{margin-left:34%;*margin-left:33.900000000000006%;}
.row-fluid .offset3{margin-left:27.5%;*margin-left:27.4%;}
.row-fluid .offset3:first-child{margin-left:25.5%;*margin-left:25.4%;}
.row-fluid .offset2{margin-left:19%;*margin-left:18.9%;}
.row-fluid .offset2:first-child{margin-left:17%;*margin-left:16.9%;}
.row-fluid .offset1{margin-left:10.5%;*margin-left:10.399999999999999%;}
.row-fluid .offset1:first-child{margin-left:8.5%;*margin-left:8.399999999999999%;}
[class*="span"].hide,.row-fluid [class*="span"].hide{display:none;}
[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right;}
.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";line-height:0;}
.container:after{clear:both;}
.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0;}
.container-fluid:after{clear:both;}
@-ms-viewport{width:device-width;}.hidden{display:none;visibility:hidden;}
.visible-phone{display:none !important;}
.visible-tablet{display:none !important;}
.hidden-desktop{display:none !important;}
.visible-desktop{display:inherit !important;}
@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}.visible-print{display:none !important;}
@media print{.visible-print{display:inherit !important;} .hidden-print{display:none !important;}}
.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}
/*]]>*/
</style>
<style type="text/css">
/*<![CDATA[*/
body{background-color:#e1e1e1;margin:0;line-height:130%}
body,table,tr,td,th,p{font-size:1.0em;font-weight:normal;font-family:Arial,Verdana;color:#000}
H1{font-family:Arial;font-size:.82em;font-weight:bold;color:#999;display:inline}
H2{background:#d6d6d6;margin-bottom:-4px;margin-top:1px;text-align:left;padding-left:10px;font-family:Arial;font-size:1.27em;font-weight:bold;color:#666}
.header{font-family:Arial;font-size:11pt;font-weight:bold;color:#666}
.small{font-family:Arial,Verdana;font-size:11pt;font-veight:normal}
#rightcol{background:#d6d6d6}
A:link{color:#00a;font-weight:normal;text-decoration:underline}
a:active,A:visited{color:#007;font-veight:normal;text-decoration:underline}
a:hover{color:#99000;font-veight:normal;text-decoration:underline}
A.ringto, A.ringto2 {font-size:1em;text-decoration:underline}
A.ringto2{font-weight:bold;}
A.top,A.top:visited{font-family:Verdana,Arial;COLOR:#FFF;text-decoration:none}
A.top:hover,A.top:active{font-family:Verdana,Arial;COLOR:#FEF;text-decoration:underline}
A.top{font-family:Verdana,Arial;text-decoration:none}
H3,H4,.bigg{font-size:1.1em;font-family:Arial,Helvetica;font-weight:bold;display:inline}
.large{font-size:1.09em;font-weight:bold;color:#003765}
.small{color:#555;font-size:1.18em}
.small2{font-size:.82em}
.small3{font-size:.92em;color:#001745}
.small4{font-size:.73em;color:#888}
.borderright{border-right:solid #DDD 1px}
a.rii{font-size:1.36em;color:red;font-weight:bold;margin-top:-10px;padding:0 16px 7px 21px;text-decoration:underline;background-image:url(http://www.stlyrics.com/r2.gif);background-repeat:no-repeat;background-position:0 2px;display:inline-block}
a.rii:hover{background-color:#ffd}
a.rii:active{position:relative;top:1px}
.muted{color:#888}
.left{text-align:left}
.center{text-align:center}
.right{text-align:right}
.div-center{margin-left:auto;margin-right:auto}
.grey{color:#999}
.song-lyrics{color:#63b1d7}
.artist-color{color: #DD0030}
hr{height:1px;border-width:0;color:#111;background-color:#111; }
.row-fluid [class*="span"] {margin-left:1%}
.up-header{height:20px;padding-right:40px}
.components-header-logo{margin-left:0;width:200px}
.components-header-banner{width:740px;margin-left:0}
.components-header-searchform{border:1px solid #aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;float:right;background:#eee}
.components-header-searchform button{border:0;background:transparent;margin:0;padding:0}
.components-header-searchform input[type=text]{background:0;color:#000;border:0;outline:0;padding:4px 8px 4px 0;width:150px;height:17px;margin-bottom:0}
.components-header-searchform img {padding-right:5px;padding-bottom:2px;-webkit-box-shadow:none;box-shadow:none}
div.components-header-breadcrumbs a,div.components-header-breadcrumbs a:visited,div.components-header-breadcrumbs a:hover{font-size:.83em;color:#555}
.components-footer{padding:30px 0 80px 0}
.components-share42-likeImage{width:36px;height:36px;background-image:url("/images/sprites/facebook-like.png");background-repeat:no-repeat}
.components-share42-likeImage iframe{opacity:0}
.layers-mainlayer-container{padding:0 10px}
.layers-mainlayer-header{margin:1px 0}
.layers-mainlayer-main{margin:6px auto}
.layers-soundtracklayer-sharing .span3{line-height:30px;height:30px}
.layers-soundtracklayer-sharing{margin:20px auto}
#disqus_thread{width:620px}
.site-index-browsest a{margin:0 6px}
.stldb-sym-index-header{line-height:30px}
.stldb-sym-index-adshare{width:65%;margin-top:20px;vertical-align:middle}
.stldb-text-index-merch{color:#888;font-weight:bold;padding-right:20px}
.stldb-text-index-top-header{line-height:30px}
.span5.stldb-text-index-video{width:280px;margin-left:20px}
.stldb-sharing{line-height:50px;width:180px}
div#plusone-div{display:block !important}
.social,.likes-ex{width:60px;height:50px;overflow:hidden;line-height:20px}
.share42init{margin:0}
.sharing-ex,.likes-ex .social .plusone,.likes-ex .social .facebook{filter:alpha(opacity=50);filter:alpha(opacity=50);-moz-opacity:.50;-khtml-opacity:.50;opacity:.50}
.sharing-ex:hover,.likes-ex .social .plusone:hover,.likes-ex .social .facebook:hover{filter:alpha(opacity=100);filter:alpha(opacity=100);-moz-opacity:1.0;-khtml-opacity:1.0;opacity:1.0}
.stldb-text-index-vsharing{width:36px}
.stldb-text-index-vsharing{position:absolute;top:50%;left:-75px;margin-top:-98px}
.stldb-text-index-downsttable{margin:0 !important}
.align_center{margin-left:11% !important;width:89% !important;position:relative}
.align_center:after{content:'';display:block;clear:both}
.align_center_to_left{position:relative;right:50%;float:right}
.align_center_to_right{position:relative;z-index:1;right:-50%;min-height:200px}
.lcu-table{line-height:130%;color:#111;margin:15px auto;padding:0}
.lcu-table-cell{margin-bottom:20px}
.sf-menu,.sf-menu *{list-style:none}.sf-menu{line-height:1;float:left;margin-bottom:1em}.sf-menu ul{position:absolute;top:-999em;width:10em}.sf-menu ul li{width:100%}.sf-menu li:hover{visibility:inherit}.sf-menu li{float:left;position:relative;background:silver}.sf-menu a{display:block;position:relative;border-left:2px solid #fff;border-top:2px solid #fff;padding:.75em 1em;text-decoration:none}.sf-menu li:hover ul,.sf-menu li.sfHover ul{left:0;top:2.5em;z-index:99}ul.sf-menu li:hover li ul,ul.sf-menu li.sfHover li ul{top:-999em}ul.sf-menu li li:hover ul,ul.sf-menu li li.sfHover ul{left:10em;top:0}ul.sf-menu li li:hover li ul,ul.sf-menu li li.sfHover li ul{top:-999em}ul.sf-menu li li li:hover ul,ul.sf-menu li li li.sfHover ul{left:10em;top:0}.sf-menu a,.sf-menu a:visited{color:#000}.sf-menu li li{background:silver}.sf-menu li li li{background:silver}.sf-menu li:hover,.sf-menu li.sfHover,.sf-menu a:focus,.sf-menu a:hover,.sf-menu a:active{background:lightgray;color:orange;outline:0}.sf-menu a.sf-with-ul{padding-right:2.25em;min-width:1px}.sf-sub-indicator{position:absolute;display:block;right:.75em;top:1.05em;width:10px;height:10px;text-indent:-999em;overflow:hidden;background:url(images/arrows-ffffff.png) no-repeat -10px -100px}a>.sf-sub-indicator{top:.8em;background:0 -100px}a:focus>.sf-sub-indicator,a:hover>.sf-sub-indicator,a:active>.sf-sub-indicator,li:hover>a>.sf-sub-indicator,li.sfHover>a>.sf-sub-indicator{background:-10px -100px}.sf-menu ul .sf-sub-indicator{background:-10px 0}.sf-menu ul a>.sf-sub-indicator{}.sf-menu ul a:focus>.sf-sub-indicator,.sf-menu ul a:hover>.sf-sub-indicator,.sf-menu ul a:active>.sf-sub-indicator,.sf-menu ul li:hover>a>.sf-sub-indicator,.sf-menu ul li.sfHover>a>.sf-sub-indicator{background:-10px 0}.sf-shadow ul{background:url(images/shadow.png) no-repeat bottom right;padding:0 8px 9px 0;-moz-border-radius-bottomleft:17px;-moz-border-radius-topright:17px;-webkit-border-top-right-radius:17px;-webkit-border-bottom-left-radius:17px}.sf-shadow ul.sf-shadow-off{background:none}
.sf-navbar{background:#bdd2ff;height:2.5em;padding-bottom:2.5em;position:relative}.sf-navbar li{background:#aabde6;position:static}.sf-navbar a{border-top:none}.sf-navbar li ul{width:44em}.sf-navbar li li{background:#bdd2ff;position:relative}.sf-navbar li li ul{width:13em}.sf-navbar li li li{width:100%}.sf-navbar ul li{width:auto;float:left}.sf-navbar a,.sf-navbar a:visited{border:none}.sf-navbar li.current{background:#bdd2ff}.sf-navbar li:hover,.sf-navbar li.sfHover,.sf-navbar li li.current,.sf-navbar a:focus,.sf-navbar a:hover,.sf-navbar a:active{background:#bdd2ff}.sf-navbar ul li:hover,.sf-navbar ul li.sfHover,ul.sf-navbar ul li:hover li,ul.sf-navbar ul li.sfHover li,.sf-navbar ul a:focus,.sf-navbar ul a:hover,.sf-navbar ul a:active{background:#d1dfff}ul.sf-navbar li li li:hover,ul.sf-navbar li li li.sfHover,.sf-navbar li li.current li.current,.sf-navbar ul li li a:focus,.sf-navbar ul li li a:hover,.sf-navbar ul li li a:active{background:#e6eeff}ul.sf-navbar .current ul,ul.sf-navbar ul li:hover ul,ul.sf-navbar ul li.sfHover ul{left:0;top:2.5em}ul.sf-navbar .current ul ul{top:-999em}.sf-navbar li li.current>a{font-weight:700}.sf-navbar ul .sf-sub-indicator{background:-10px -100px}.sf-navbar ul a>.sf-sub-indicator{background:0 -100px}.sf-navbar ul a:focus>.sf-sub-indicator,.sf-navbar ul a:hover>.sf-sub-indicator,.sf-navbar ul a:active>.sf-sub-indicator,.sf-navbar ul li:hover>a>.sf-sub-indicator,.sf-navbar ul li.sfHover>a>.sf-sub-indicator{background:-10px -100px}.sf-navbar>li>ul{background:none;padding:0;-moz-border-radius-bottomleft:0;-moz-border-radius-topright:0;-webkit-border-top-right-radius:0;-webkit-border-bottom-left-radius:0}
.sf-menu{margin:0;padding:0;font-size:1em;color:#FFF;font-weight:bold}
.sf-menu>li{margin:5px 0}
.sf-navbar{height:auto}
.sf-menu a.sf-with-ul,.sf-menu a,.sf-menu a:visited{color:#666;font-weight:bold}
.sf-navbar,.sf-navbar li,.sf-navbar li.current{background:transparent}
.sf-navbar li li,.sf-navbar li ul{background:#eee}
.sf-navbar li ul{width:36em;border:1px solid #666;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;color:#fff;padding-left:12px}
.sf-navbar li li a{padding:15px 5px}
.sf-navbar li:hover,.sf-navbar li.sfHover,.sf-navbar li li.current,.sf-navbar li a:hover,.sf-navbar a:focus,.sf-navbar a:hover,.sf-navbar a:active{background:transparent;color:#000}
.sf-navbar ul li:hover,.sf-navbar ul li.sfHover,ul.sf-navbar ul li:hover li,ul.sf-navbar ul li.sfHover li,.sf-navbar ul a:focus,.sf-navbar ul a:hover,.sf-navbar ul a:active{background:#fff;color:#000}
.sf-menu li:hover ul,.sf-menu li.sfHover ul{left:-10px;top:30px;z-index:99}
.sf-menu a.sf-with-ul{padding-right:0}
.sf-menu a{padding:0;text-decoration:none}
.social{margin:3px 0}
.social-horizontal{float:left}
.social-vertical{margin:2px 0}
.whites>.list-view .items{background:#FFF}
.list-view .pager{text-align:center}
ul.yiiPager{border:0;margin:0 auto;padding:0;line-height:100%;display:inline}
ul.yiiPager li{display:inline}
ul.yiiPager a:link,ul.yiiPager a:visited{font-weight:bold;padding:1px 6px;text-decoration:none}
ul.yiiPager .page a{font-weight:normal}
ul.yiiPager .selected a{background:#007;color:#fff;font-weight:bold}
ul.yiiPager .hidden a{border:solid 1px #dedede}
/*]]>*/
</style>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="/assets/320fe20a/mPrint.js"></script>
<script type="text/javascript" src="/assets/8a4f4922/js/superfish.js" async="async"></script>
<script type="text/javascript" src="/assets/8a4f4922/js/hoverIntent.js" async="async"></script>
<script type="text/javascript" src="/assets/8a4f4922/js/CDropDownMenu.js" async="async"></script>
<title>Richie Havens &mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens</title><meta name="description" content="Lady Madonna lyrics by Richie Havens from album 20th Century Masters - The Millennium Collection: The Best Of Richie Havens. Lady Madonna, children at your feet Wonder how you manage to make ends meet Who finds the money" />
<meta name="keywords" content=" Richie Havens, Lady Madonna Lyrics, album, 20th Century Masters - The Millennium Collection: The Best Of Richie Havens, song, cd, text, artist" />
<meta property="twitter:title" content="Richie Havens &amp;mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens" />
<meta property="twitter:image:src" content="" />
<meta property="twitter:card" content="summary" />
<meta property="twitter:site" content="@stlyricscom" />
<meta property="twitter:creator" content="@stlyricscom" />
<meta property="twitter:domain" content="http://www.stlyrics.com/songs/r/richiehavens48961/ladymadonna2069109.html" />
<meta itemprop="name" content="Richie Havens &amp;mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens">
<meta itemprop="image" content="">
<meta itemprop="description" content="Lady Madonna lyrics by Richie Havens from album 20th Century Masters - The Millennium Collection: The Best Of Richie Havens. Lady Madonna, children at your feet Wonder how you manage to make ends meet Who finds the money">
<!-- <meta name="viewport" content="width=1024">-->
<meta name="viewport" content="width=device-width">
<meta name="robots" content="ALL"/>
</head>
<body>
<!-- Begin comScore Tag -->
<script>
var _comscore = _comscore || [];
var urlo = document.URL.replace('http://', '');
_comscore.push({
c1: 2,
c2: "6772046",
c3: "",
c4: urlo,
c5: "",
c6: "",
c15: ""
});
(function() {
var s = document.createElement("script"), el =
document.getElementsByTagName("script")[0]; s.async = true;
s.src = (document.location.protocol == "https:" ? "https://sb" : "http://b") +
".scorecardresearch.com/beacon.js";
el.parentNode.insertBefore(s, el);
})();
</script>
<!-- End comScore Tag -->
<div class="container">
<div class="row up-header">
<div class="pull-right">
<div class="components-header-breadcrumbs">
<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/site/index.html" itemprop="url"><span itemprop="title">Home</span></a></span> &raquo; <span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/songs/r.html" itemprop="url"><span itemprop="title">R</span></a></span> &raquo; <span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/songs/r/richiehavens48961.html" itemprop="url"><span itemprop="title">Richie Havens</span></a></span> &raquo; <h1><span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><span itemprop="title">Lady Madonna Lyrics</span></span></h1></div> </div>
</div>
<div class="row-fluid">
<div class="span3 components-header-logo">
<a href="/index.htm">
<img SRC="/soundtrack-lyrics.gif" WIDTH="182" HEIGHT="50" ALT="Song Lyrics. Letter: ">
</a>
</div>
<div class="span9 components-header-banner">
<!-- TribalFusion 728x90 -->
<script type="text/javascript">
e9 = new Object();
e9.size = "728x90,468x60";
</script>
<script type="text/javascript" src="http://tags.expo9.exponential.com/tags/STLyrics/ROS/tags.js"></script>
</div>
</div>
</div>
<div class="container">
<div class="row-fluid">
<div class="span3" style="margin-left: 10px;">
<ul id="menu54217dd3ada18" class="sf-menu sf-navbar">
<li><a href="#">ARTISTS &#9660;</a>
<ul>
<li><a href="/songs/a.html">A</a></li>
<li><a href="/songs/b.html">B</a></li>
<li><a href="/songs/c.html">C</a></li>
<li><a href="/songs/d.html">D</a></li>
<li><a href="/songs/e.html">E</a></li>
<li><a href="/songs/f.html">F</a></li>
<li><a href="/songs/g.html">G</a></li>
<li><a href="/songs/h.html">H</a></li>
<li><a href="/songs/i.html">I</a></li>
<li><a href="/songs/j.html">J</a></li>
<li><a href="/songs/k.html">K</a></li>
<li><a href="/songs/l.html">L</a></li>
<li><a href="/songs/m.html">M</a></li>
<li><a href="/songs/n.html">N</a></li>
<li><a href="/songs/o.html">O</a></li>
<li><a href="/songs/p.html">P</a></li>
<li><a href="/songs/q.html">Q</a></li>
<li><a href="/songs/r.html">R</a></li>
<li><a href="/songs/s.html">S</a></li>
<li><a href="/songs/t.html">T</a></li>
<li><a href="/songs/u.html">U</a></li>
<li><a href="/songs/v.html">V</a></li>
<li><a href="/songs/w.html">W</a></li>
<li><a href="/songs/x.html">X</a></li>
<li><a href="/songs/y.html">Y</a></li>
<li><a href="/songs/z.html">Z</a></li>
<li><a href="/songs/0-9.html">#</a></li>
</ul>
</li>
</ul><div style="clear:both;"></div>
</div>
<div class="span3">
<ul id="menu54217dd3ae27b" class="sf-menu sf-navbar">
<li><a href="#">SOUNDTRACKS &#9660;</a>
<ul>
<li><a href="/a.htm">A</a></li>
<li><a href="/b.htm">B</a></li>
<li><a href="/c.htm">C</a></li>
<li><a href="/d.htm">D</a></li>
<li><a href="/e.htm">E</a></li>
<li><a href="/f.htm">F</a></li>
<li><a href="/g.htm">G</a></li>
<li><a href="/h.htm">H</a></li>
<li><a href="/i.htm">I</a></li>
<li><a href="/j.htm">J</a></li>
<li><a href="/k.htm">K</a></li>
<li><a href="/l.htm">L</a></li>
<li><a href="/m.htm">M</a></li>
<li><a href="/n.htm">N</a></li>
<li><a href="/o.htm">O</a></li>
<li><a href="/p.htm">P</a></li>
<li><a href="/q.htm">Q</a></li>
<li><a href="/r.htm">R</a></li>
<li><a href="/s.htm">S</a></li>
<li><a href="/t.htm">T</a></li>
<li><a href="/u.htm">U</a></li>
<li><a href="/v.htm">V</a></li>
<li><a href="/w.htm">W</a></li>
<li><a href="/x.htm">X</a></li>
<li><a href="/y.htm">Y</a></li>
<li><a href="/z.htm">Z</a></li>
<li><a href="/19.htm">#</a></li>
</ul>
</li>
</ul><div style="clear:both;"></div>
</div>
<div class="span3">
<ul id="yw0" class="sf-menu sf-navbar">
<li><a href="/songs/new.html">New Songs</a></li>
</ul><div style="clear:both;"></div>
</div>
<div class="span3">
<form action="http://www.google.com" id="cse-search-box">
<div>
<input type="hidden" name="cx" value="partner-pub-1248082249428003:4249914101" />
<input type="hidden" name="ie" value="UTF-8" />
<input type="text" name="q" size="17" />
<input type="submit" name="sa" value="Search" />
</div>
</form>
<script type="text/javascript" async src="http://www.google.com/coop/cse/brand?form=cse-search-box&amp;lang=en"></script>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span10">
<div class="container-fluid layers-mainlayer-container">
<div class="row-fluid layers-mainlayer-header">
<div class="span12">
<div class="row-fluid">
<div class="span12 stldb-text-index-top-header">
<h2><span class="artist-color">Lady Madonna</span> by <a href="/songs/r/richiehavens48961.html">Richie Havens</a>
&nbsp;<iframe width="26" scrolling="no" height="17" marginwidth="0" marginheight="0" style="border: 0px none; padding-left:0px" allowtransparency="true" src="http://jmn.jangonetwork.com/cl?cust_params=j_artist=Richie%20Havens&amp;j_title=Lady%20Madonna"></iframe>
</h2>
</div>
</div>
<div class="row-fluid">
<div class="span4 stldb-text-index-merch pull-right">
<div class="stldb-text-index-merch">
<a href="http://www.amazon.com/exec/obidos/external-search/103-7184989-1727801?mode=music&amp;keyword=Richie%20Havens%2020th%20Century%20Masters%20-%20The%20Millennium%20Collection%3A%20The%20Best%20Of%20Richie%20Havens&amp;tag=wwwstlyrics-20" target="_blank" rel="nofollow">CD</a>
<span class="bigg">&nbsp;&#183;&nbsp;</span>
<a href="http://www.amazon.com/exec/obidos/external-search/103-7184989-1727801?mode=dvd&amp;keyword=Richie%20Havens%2020th%20Century%20Masters%20-%20The%20Millennium%20Collection%3A%20The%20Best%20Of%20Richie%20Havens&amp;tag=wwwstlyrics-20" target="_blank" rel="nofollow">DVD</a>
<span class="bigg">&nbsp;&#183;&nbsp;</span>
<a href="http://www.sheetmusicplus.com/a/phrase.html?aff_id=68820&amp;phrase=Richie%20Havens%20Lady%20Madonna" target="_blank" rel="nofollow">Sheet music</a>
</div>
</div>
</div>
</div>
</div>
<br>
<div class="row-fluid layers-mainlayer-upbunner center">
<br/>
<!-- Stlyrics 728x90 v3 -->
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-1248082249428003"
data-ad-slot="7304846179"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
<div class="row-fluid layers-mainlayer-main">
<div class="span12 layers-mainlayer-content">
<div class="row-fluid">
<div class="span11 align_center offset1">
<div class="align_center_to_left">
<div class="align_center_to_right">
<div class="stldb-text-index-vsharing">
<div class="likes-ex">
<div class="social">
<!--For details: http://developers.google.com/+/plugins/+1button/ -->
<div class="plusone social-vertical">
<div class="g-plusone" data-size="medium" data-annotation="none"></div>
</div>
<div class="facebook social-vertical">
<!-- <div id="fb-root"></div>-->
<iframe src="http://www.facebook.com/plugins/like.php?locale=en_US&amp;app_id=133000596876438&amp;href=http%3A%2F%2Fwww.stlyrics.com%2Fsongs%2Fr%2Frichiehavens48961%2Fladymadonna2069109.html&amp;send=false&amp;layout=button&amp;width=&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=trebuchet+ms&amp;height=20" style="border:none; overflow:hidden; width:; height:70px;"></iframe>
</div>
</div>
</div>
<div class='sharing-ex '>
<div class="share42init" data-margin="0" data-url="http://www.stlyrics.com/index.php/songs/r/richiehavens48961/ladymadonna2069109.html" data-title="Richie Havens &amp;mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens" data-image="" data-description="Lady Madonna lyrics by Richie Havens from album 20th Century Masters - The Millennium Collection: The Best Of Richie Havens. Lady Madonna, children at your feet Wonder how you manage to make ends meet Who finds the money"></div><div class="mprint"><a id="mprint"><img title="Print" src="/assets/320fe20a/printer.png" alt="" /></a></div></div>
<script type="text/javascript" async="async" src="http://www.stlyrics.com/themes/front/share42/share42.js"></script>
</div>
<div id="page">
<span class="slarge visible-print">Lady Madonna</span>
Lady Madonna, children at your feet<br />
Wonder how you manage to make ends meet<br />
Who finds the money when you pay the rent?<br />
Did you think that money was Heaven sent?<br />
<br />
Friday night arrives without a suitcase<br />
Sunday morning creeping like a nun<br />
Monday's child has learned to tie his bootlegs<br />
See how they run<br />
<br />
Singing, Lady Madonna lying on the bed<br />
Listen to the music runnin' through your head<br />
'Round your head, 'round your head<br />
Oh no, oh no<br />
<br />
Tuesday afternoon is never ending<br />
Wednesday morning papers didn't come<br />
Thursday night your stocking needed mending<br />
See how they run<br />
<br />
Singing, Lady Madonna, children at your feet<br />
Wonder how you manage to make ends meet<br />
How you manage to make ends meet<br />
How do you manage to make ends meet<br />
<br />
Lady Madonna<br />
</div>
<br>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<script type="text/javascript">
/* ToneFuse */
(function() {
var opts = {
artist: "",
song: "Lady Madonna",
genre: "",
adunit_id: 39382129,
div_id: "cf_async_" + Math.floor((Math.random() * 999999999)),
hostname: "srv.tonefuse.com"
};
document.write('<div id="'+opts.div_id+'"></div>');var c=function(){cf.showAsyncAd(opts)};if(window.cf)c();else{cf_async=!0;var
r=document.createElement("script"),s=document.getElementsByTagName("script")[0];r.async=!0;r.src="//"+opts.hostname+"/showads/showad.js";r.readyState?r.onreadystatechange=function(){if("loaded"==r.readyState||"complete"==r.readyState)r.onreadystatechange=null,c()}:r.onload=c;s.parentNode.insertBefore(r,s)};
})();
</script>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12 center">
<br/>
<!-- Stlyrics 728x90 v2 -->
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-1248082249428003"
data-ad-slot="6395019374"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<br/>
</div>
</div>
<div class="row-fluid layers-soundtracklayer-sharing">
<div class="span3">
</div>
<div class="span3">
<div class='sharing-ex '>
<div class="share42init" data-margin="0" data-url="http://www.stlyrics.com/index.php/songs/r/richiehavens48961/ladymadonna2069109.html" data-title="Richie Havens &amp;mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens" data-image="" data-description="Lady Madonna lyrics by Richie Havens from album 20th Century Masters - The Millennium Collection: The Best Of Richie Havens. Lady Madonna, children at your feet Wonder how you manage to make ends meet Who finds the money"></div><div class="mprint"></div></div>
<script type="text/javascript" async="async" src="http://www.stlyrics.com/themes/front/share42/share42.js"></script>
</div>
<div class="pull-right">
<div class="stldb-text-index-merch">
<a href="http://www.amazon.com/exec/obidos/external-search/103-7184989-1727801?mode=music&amp;keyword=Richie%20Havens%2020th%20Century%20Masters%20-%20The%20Millennium%20Collection%3A%20The%20Best%20Of%20Richie%20Havens&amp;tag=wwwstlyrics-20" target="_blank" rel="nofollow">CD</a>
<span class="bigg">&nbsp;&#183;&nbsp;</span>
<a href="http://www.amazon.com/exec/obidos/external-search/103-7184989-1727801?mode=dvd&amp;keyword=Richie%20Havens%2020th%20Century%20Masters%20-%20The%20Millennium%20Collection%3A%20The%20Best%20Of%20Richie%20Havens&amp;tag=wwwstlyrics-20" target="_blank" rel="nofollow">DVD</a>
<span class="bigg">&nbsp;&#183;&nbsp;</span>
<a href="http://www.sheetmusicplus.com/a/phrase.html?aff_id=68820&amp;phrase=Richie%20Havens%20Lady%20Madonna" target="_blank" rel="nofollow">Sheet music</a>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12 comment-wrap">
<div class="row-fluid">
<div class="span12">
<span class="bigg">Comments</span> <a id="comments"></a> <br><br>
<div class="row-fluid">
<div class="span12">
<div class="fb-comments" data-href="http://www.stlyrics.com/index.php/songs/r/richiehavens48961/ladymadonna2069109.html" data-width="620" data-colorscheme="light" data-num-posts="5"></div>
</div>
</div>
<div class="row-fluid">
<div class="span11 center">
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'stlyrics'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="span2" style="padding-top: 10px;">
<!-- Stlyrics 160x600 sky v2 -->
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:inline-block;width:160px;height:600px"
data-ad-client="ca-pub-1248082249428003"
data-ad-slot="4211778971"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</div>
</div>
<div class="container components-footer">
<div class="row-fluid">
<div class="span7 offset2 center">
&nbsp;<a href="/dmca.htm" class="ringto2">DMCA</a>
&nbsp;&#183;&nbsp; <a href="/privacy.htm" class="ringto2">Privacy</a>
&nbsp;&#183;&nbsp; <a href="/contact.htm" class="ringto2">Contact </a>
</div>
<div class="span3 center">
&copy; STLyrics.com 2014 </div>
</div>
</div>
<div id="fb-root"></div><script type="text/javascript">
/*<![CDATA[*/
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/platform.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
window.fbAsyncInit = function(){FB.init({'appId':'133000596876438','status':true,'cookie':true,'xfbml':true,'oauth':true,'frictionlessRequests':false});};
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = '//connect.facebook.net/en_US/all.js';
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
jQuery(function($) {
$(function(){
// Hook up the print link.
$( "#mprint" )
.attr( "href", "javascript:void( 0 )" )
.click(
function(){
// Print the DIV.
$( "#page" ).print({"documentName":"Print Richie Havens &mdash; Lady Madonna Lyrics | Album: 20th Century Masters - The Millennium Collection: The Best Of Richie Havens","cssFile":"\/assets\/320fe20a\/mprint.css","debug":false,"dbgHeight":"100%","dbgWidth":"100%","timeOut":60});
// Cancel click event.
return( false );
});
});
});
/*]]>*/
</script>
</body>
</html>

View file

@ -1,3 +1,70 @@
Amsterdam: |
Dans le port d'Amsterdam
Y a des marins qui chantent
Les rêves qui les hantent
Au large d'Amsterdam
Dans le port d'Amsterdam
Y a des marins qui dorment
Comme des oriflammes
Le long des berges mornes
Dans le port d'Amsterdam
Y a des marins qui meurent
Pleins de bière et de drames
Aux premières lueurs
Mais dans le port d'Amsterdam
Y a des marins qui naissent
Dans la chaleur épaisse
Des langueurs océanes
Dans le port d'Amsterdam
Y a des marins qui mangent
Sur des nappes trop blanches
Des poissons ruisselants
Ils vous montrent des dents
A croquer la fortune
A décroisser la lune
A bouffer des haubans
Et ça sent la morue
Jusque dans le coeur des frites
Que leurs grosses mains invitent
A revenir en plus
Puis se lèvent en riant
Dans un bruit de tempête
Referment leur braguette
Et sortent en rotant
Dans le port d'Amsterdam
Y a des marins qui dansent
En se frottant la panse
Sur la panse des femmes
Et ils tournent et ils dansent
Comme des soleils crachés
Dans le son déchiré
D'un accordéon rance
Ils se tordent le cou
Pour mieux s'entendre rire
Jusqu'à ce que tout à coup
L'accordéon expire
Alors le geste grave
Alors le regard fier
Ils ramènent leur batave
Jusqu'en pleine lumière
Dans le port d'Amsterdam
Y a des marins qui boivent
Et qui boivent et reboivent
Et qui reboivent encore
Ils boivent à la santé
Des putains d'Amsterdam
De Hambourg ou d'ailleurs
Enfin ils boivent aux dames
Qui leur donnent leur joli corps
Qui leur donnent leur vertu
Pour une pièce en or
Et quand ils ont bien bu
Se plantent le nez au ciel
Se mouchent dans les étoiles
Et ils pissent comme je pleure
Sur les femmes infidèles
Dans le port d'Amsterdam
Lady_Madonna: |
Lady Madonna, children at your feet
Wonder how you manage to make ends meet

View file

@ -165,6 +165,13 @@ class ConvertCliTest(unittest.TestCase, TestHelper):
mediafile = MediaFile(converted)
self.assertEqual(mediafile.images[0].data, image_data)
def test_skip_existing(self):
converted = os.path.join(self.convert_dest, 'converted.mp3')
self.touch(converted, content='XXX')
self.run_command('convert', '--yes', self.item.path)
with open(converted, 'r') as f:
self.assertEqual(f.read(), 'XXX')
class NeverConvertLossyFilesTest(unittest.TestCase, TestHelper):
"""Test the effect of the `never_convert_lossy_files` option.

View file

@ -112,6 +112,14 @@ class DateQueryTest(_common.LibTestCase):
self.assertEqual(len(matched), 0)
class DateQueryConstructTest(unittest.TestCase):
def test_long_numbers(self):
DateQuery('added', '1409830085..1412422089')
def test_too_many_components(self):
DateQuery('added', '12-34-56-78')
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -25,6 +25,10 @@ from tempfile import mkstemp
# Fixture: concrete database and model classes. For migration tests, we
# have multiple models with different numbers of fields.
class TestSort(dbcore.query.FieldSort):
pass
class TestModel1(dbcore.Model):
_table = 'test'
_flex_table = 'testflex'
@ -35,6 +39,9 @@ class TestModel1(dbcore.Model):
_types = {
'some_float_field': dbcore.types.FLOAT,
}
_sorts = {
'some_sort': TestSort,
}
@classmethod
def _getters(cls):
@ -455,6 +462,10 @@ class SortFromStringsTest(unittest.TestCase):
self.assertIsInstance(s, dbcore.query.MultipleSort)
self.assertIsInstance(s.sorts[0], dbcore.query.SlowFieldSort)
def test_special_sort(self):
s = self.sfs(['some_sort+'])
self.assertIsInstance(s.sorts[0], TestSort)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -15,19 +15,42 @@
import os.path
import _common
from _common import unittest
from helper import TestHelper
from helper import TestHelper, capture_log
from nose.plugins.skip import SkipTest
from beets.mediafile import MediaFile
from beets import config
from beets.util import syspath
from beets.util.artresizer import ArtResizer
def require_artresizer_compare(test):
def wrapper(*args, **kwargs):
if not ArtResizer.shared.can_compare:
raise SkipTest()
else:
return test(*args, **kwargs)
wrapper.__name__ = test.__name__
return wrapper
class EmbedartCliTest(unittest.TestCase, TestHelper):
artpath = os.path.join(_common.RSRC, 'image-2x3.jpg')
small_artpath = os.path.join(_common.RSRC, 'image-2x3.jpg')
abbey_artpath = os.path.join(_common.RSRC, 'abbey.jpg')
abbey_similarpath = os.path.join(_common.RSRC, 'abbey-similar.jpg')
abbey_differentpath = os.path.join(_common.RSRC, 'abbey-different.jpg')
def setUp(self):
self.setup_beets() # Converter is threaded
self.load_plugins('embedart')
with open(self.artpath) as f:
def _setup_data(self, artpath=None):
if not artpath:
artpath = self.small_artpath
with open(syspath(artpath)) as f:
self.image_data = f.read()
def tearDown(self):
@ -35,22 +58,57 @@ class EmbedartCliTest(unittest.TestCase, TestHelper):
self.teardown_beets()
def test_embed_art_from_file(self):
self._setup_data()
album = self.add_album_fixture()
item = album.items()[0]
self.run_command('embedart', '-f', self.artpath)
mediafile = MediaFile(item.path)
self.run_command('embedart', '-f', self.small_artpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data)
def test_embed_art_from_album(self):
self._setup_data()
album = self.add_album_fixture()
item = album.items()[0]
album.artpath = self.artpath
album.artpath = self.small_artpath
album.store()
self.run_command('embedart')
mediafile = MediaFile(item.path)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data)
def test_art_file_missing(self):
self.add_album_fixture()
with capture_log() as logs:
self.run_command('embedart', '-f', '/doesnotexist')
self.assertIn(u'embedart: could not read image file:', ''.join(logs))
@require_artresizer_compare
def test_reject_different_art(self):
self._setup_data(self.abbey_artpath)
album = self.add_album_fixture()
item = album.items()[0]
self.run_command('embedart', '-f', self.abbey_artpath)
config['embedart']['compare_threshold'] = 20
self.run_command('embedart', '-f', self.abbey_differentpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data,
'Image written is not {0}'.format(
self.abbey_artpath))
@require_artresizer_compare
def test_accept_similar_art(self):
self._setup_data(self.abbey_similarpath)
album = self.add_album_fixture()
item = album.items()[0]
self.run_command('embedart', '-f', self.abbey_artpath)
config['embedart']['compare_threshold'] = 20
self.run_command('embedart', '-f', self.abbey_similarpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data,
'Image written is not {0}'.format(
self.abbey_similarpath))
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -588,6 +588,22 @@ class UniquePathTest(_common.TestCase):
self.assertEqual(path, os.path.join(self.base, 'x.3.mp3'))
class MkDirAllTest(_common.TestCase):
def test_parent_exists(self):
path = os.path.join(self.temp_dir, 'foo', 'bar', 'baz', 'qux.mp3')
util.mkdirall(path)
self.assertTrue(os.path.isdir(
os.path.join(self.temp_dir, 'foo', 'bar', 'baz')
))
def test_child_does_not_exist(self):
path = os.path.join(self.temp_dir, 'foo', 'bar', 'baz', 'qux.mp3')
util.mkdirall(path)
self.assertTrue(not os.path.exists(
os.path.join(self.temp_dir, 'foo', 'bar', 'baz', 'qux.mp3')
))
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -39,10 +39,13 @@ class AutotagStub(object):
autotagger returns.
"""
NONE = 'NONE'
IDENT = 'IDENT'
GOOD = 'GOOD'
BAD = 'BAD'
NONE = 'NONE'
IDENT = 'IDENT'
GOOD = 'GOOD'
BAD = 'BAD'
MISSING = 'MISSING'
"""Generate an album match for all but one track
"""
length = 2
matching = IDENT
@ -50,15 +53,21 @@ class AutotagStub(object):
def install(self):
self.mb_match_album = autotag.mb.match_album
self.mb_match_track = autotag.mb.match_track
self.mb_album_for_id = autotag.mb.album_for_id
self.mb_track_for_id = autotag.mb.track_for_id
autotag.mb.match_album = self.match_album
autotag.mb.match_track = self.match_track
autotag.mb.album_for_id = self.album_for_id
autotag.mb.track_for_id = self.track_for_id
return self
def restore(self):
autotag.mb.match_album = self.mb_match_album
autotag.mb.match_track = self.mb_match_album
autotag.mb.album_for_id = self.mb_album_for_id
autotag.mb.track_for_id = self.mb_track_for_id
def match_album(self, albumartist, album, tracks):
if self.matching == self.IDENT:
@ -72,6 +81,9 @@ class AutotagStub(object):
for i in range(self.length):
yield self._make_album_match(albumartist, album, tracks, i + 1)
elif self.matching == self.MISSING:
yield self._make_album_match(albumartist, album, tracks, missing=1)
def match_track(self, artist, title):
yield TrackInfo(
title=title.replace('Tag', 'Applied'),
@ -81,6 +93,12 @@ class AutotagStub(object):
length=1
)
def album_for_id(self, mbid):
return None
def track_for_id(self, mbid):
return None
def _make_track_match(self, artist, album, number):
return TrackInfo(
title=u'Applied Title %d' % number,
@ -89,7 +107,7 @@ class AutotagStub(object):
length=1
)
def _make_album_match(self, artist, album, tracks, distance=0):
def _make_album_match(self, artist, album, tracks, distance=0, missing=0):
if distance:
id = ' ' + 'M' * distance
else:
@ -101,7 +119,7 @@ class AutotagStub(object):
album = album.replace('Tag', 'Applied') + id
trackInfos = []
for i in range(tracks):
for i in range(tracks - missing):
trackInfos.append(self._make_track_match(artist, album, i + 1))
return AlbumInfo(
@ -536,6 +554,13 @@ class ImportTest(_common.TestCase, ImportHelper):
self.importer.run()
self.assertEqual(len(self.lib.albums()), 1)
def test_unmatched_tracks_not_added(self):
self._create_import_dir(2)
self.matcher.matching = self.matcher.MISSING
self.importer.add_choice(importer.action.APPLY)
self.importer.run()
self.assertEqual(len(self.lib.items()), 1)
class ImportTracksTest(_common.TestCase, ImportHelper):
"""Test TRACKS and APPLY choice.
@ -875,11 +900,10 @@ class InferAlbumDataTest(_common.TestCase):
self.task = importer.ImportTask(paths=['a path'], toppath='top path',
items=self.items)
self.task.set_null_candidates()
def test_asis_homogenous_single_artist(self):
self.task.set_choice(importer.action.ASIS)
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertFalse(self.items[0].comp)
self.assertEqual(self.items[0].albumartist, self.items[2].artist)
@ -888,7 +912,7 @@ class InferAlbumDataTest(_common.TestCase):
self.items[1].artist = 'some other artist'
self.task.set_choice(importer.action.ASIS)
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertTrue(self.items[0].comp)
self.assertEqual(self.items[0].albumartist, 'Various Artists')
@ -898,7 +922,7 @@ class InferAlbumDataTest(_common.TestCase):
self.items[1].artist = 'some other artist'
self.task.set_choice(importer.action.ASIS)
self.task.infer_album_fields()
self.task.align_album_level_fields()
for item in self.items:
self.assertTrue(item.comp)
@ -908,7 +932,7 @@ class InferAlbumDataTest(_common.TestCase):
self.items[0].artist = 'another artist'
self.task.set_choice(importer.action.ASIS)
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertFalse(self.items[0].comp)
self.assertEqual(self.items[0].albumartist, self.items[2].artist)
@ -921,7 +945,7 @@ class InferAlbumDataTest(_common.TestCase):
item.mb_albumartistid = 'some album artist id'
self.task.set_choice(importer.action.ASIS)
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertEqual(self.items[0].albumartist,
'some album artist')
@ -931,7 +955,7 @@ class InferAlbumDataTest(_common.TestCase):
def test_apply_gets_artist_and_id(self):
self.task.set_choice(AlbumMatch(0, None, {}, set(), set())) # APPLY
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertEqual(self.items[0].albumartist, self.items[0].artist)
self.assertEqual(self.items[0].mb_albumartistid,
@ -943,7 +967,7 @@ class InferAlbumDataTest(_common.TestCase):
item.mb_albumartistid = 'some album artist id'
self.task.set_choice(AlbumMatch(0, None, {}, set(), set())) # APPLY
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertEqual(self.items[0].albumartist,
'some album artist')
@ -954,10 +978,27 @@ class InferAlbumDataTest(_common.TestCase):
self.items = [self.items[0]]
self.task.items = self.items
self.task.set_choice(importer.action.ASIS)
self.task.infer_album_fields()
self.task.align_album_level_fields()
self.assertFalse(self.items[0].comp)
def test_album_info():
"""Create an AlbumInfo object for testing.
"""
track_info = TrackInfo(
title=u'new title',
track_id=u'trackid',
)
album_info = AlbumInfo(
artist=u'artist',
album=u'album',
tracks=[track_info],
album_id=u'albumid',
artist_id=u'artistid',
)
return album_info
class ImportDuplicateAlbumTest(unittest.TestCase, TestHelper):
def setUp(self):
@ -969,18 +1010,7 @@ class ImportDuplicateAlbumTest(unittest.TestCase, TestHelper):
# Create duplicate through autotagger
self.match_album_patcher = patch('beets.autotag.mb.match_album')
self.match_album = self.match_album_patcher.start()
track_info = TrackInfo(
title=u'new title',
track_id=u'trackid',
)
album_info = AlbumInfo(
artist=u'artist',
album=u'album',
tracks=[track_info],
album_id=u'albumid',
artist_id=u'artistid',
)
self.match_album.return_value = iter([album_info])
self.match_album.return_value = iter([test_album_info()])
# Create import session
self.importer = self.create_importer()
@ -1004,6 +1034,29 @@ class ImportDuplicateAlbumTest(unittest.TestCase, TestHelper):
item = self.lib.items().get()
self.assertEqual(item.title, u'new title')
def test_no_autotag_keeps_duplicate_album(self):
config['import']['autotag'] = False
item = self.lib.items().get()
self.assertEqual(item.title, u't\xeftle 0')
self.assertTrue(os.path.isfile(item.path))
# Imported item has the same artist and album as the one in the
# library.
import_file = os.path.join(self.importer.paths[0],
'album 0', 'track 0.mp3')
import_file = MediaFile(import_file)
import_file.artist = item['artist']
import_file.albumartist = item['artist']
import_file.album = item['album']
import_file.title = 'new title'
self.importer.default_resolution = self.importer.Resolution.REMOVE
self.importer.run()
self.assertTrue(os.path.isfile(item.path))
self.assertEqual(len(self.lib.albums()), 2)
self.assertEqual(len(self.lib.items()), 2)
def test_keep_duplicate_album(self):
self.importer.default_resolution = self.importer.Resolution.KEEPBOTH
self.importer.run()
@ -1337,6 +1390,89 @@ class MultiDiscAlbumsInDirTest(_common.TestCase):
self.assertEquals(len(albums), 0)
class ReimportTest(unittest.TestCase, ImportHelper):
"""Test "re-imports", in which the autotagging machinery is used for
music that's already in the library.
This works by importing new database entries for the same files and
replacing the old data with the new data. We also copy over flexible
attributes and the added date.
"""
def setUp(self):
self.setup_beets()
# The existing album.
album = self.add_album_fixture()
album.added = 4242.0
album.foo = u'bar' # Some flexible attribute.
album.store()
item = album.items().get()
item.baz = u'qux'
item.added = 4747.0
item.store()
# Set up an import pipeline with a "good" match.
self.matcher = AutotagStub().install()
self.matcher.matching = AutotagStub.GOOD
def tearDown(self):
self.teardown_beets()
self.matcher.restore()
def _setup_session(self, singletons=False):
self._setup_import_session(self._album().path, singletons=singletons)
self.importer.add_choice(importer.action.APPLY)
def _album(self):
return self.lib.albums().get()
def _item(self):
return self.lib.items().get()
def test_reimported_album_gets_new_metadata(self):
self._setup_session()
self.assertEqual(self._album().album, u'\xe4lbum')
self.importer.run()
self.assertEqual(self._album().album, u'the album')
def test_reimported_album_preserves_flexattr(self):
self._setup_session()
self.importer.run()
self.assertEqual(self._album().foo, u'bar')
def test_reimported_album_preserves_added(self):
self._setup_session()
self.importer.run()
self.assertEqual(self._album().added, 4242.0)
def test_reimported_album_preserves_item_flexattr(self):
self._setup_session()
self.importer.run()
self.assertEqual(self._item().baz, u'qux')
def test_reimported_album_preserves_item_added(self):
self._setup_session()
self.importer.run()
self.assertEqual(self._item().added, 4747.0)
def test_reimported_item_gets_new_metadata(self):
self._setup_session(True)
self.assertEqual(self._item().title, u't\xeftle 0')
self.importer.run()
self.assertEqual(self._item().title, u'full')
def test_reimported_item_preserves_flexattr(self):
self._setup_session(True)
self.importer.run()
self.assertEqual(self._item().baz, u'qux')
def test_reimported_item_preserves_added(self):
self._setup_session(True)
self.importer.run()
self.assertEqual(self._item().added, 4747.0)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# This file is part of beets.
# Copyright 2014, Fabrice Laporte.
#
@ -14,9 +15,12 @@
"""Tests for the 'lyrics' plugin."""
import os
import _common
from _common import unittest
from beetsplug import lyrics
from beets.library import Item
from beets.util import confit
class LyricsPluginTest(unittest.TestCase):
@ -111,11 +115,183 @@ class LyricsPluginTest(unittest.TestCase):
lyrics.remove_credits("""Lyrics brought by example.com"""),
""
)
# don't remove 2nd verse for the only reason it contains 'lyrics' word
text = """Look at all the shit that i done bought her
See lyrics ain't nothin
if the beat aint crackin"""
self.assertEqual(lyrics.remove_credits(text), text)
def test_is_lyrics(self):
texts = ['LyricsMania.com - Copyright (c) 2013 - All Rights Reserved']
texts += ["""All material found on this site is property\n
of mywickedsongtext brand"""]
for t in texts:
self.assertFalse(lyrics.is_lyrics(t))
def test_slugify(self):
text = u"http://site.com/çafe-au_lait(boisson)"
self.assertEqual(lyrics.slugify(text), 'http://site.com/cafe_au_lait')
def test_scrape_strip_cruft(self):
text = u"""<!--lyrics below-->
&nbsp;one
<br class='myclass'>
two !
<br><br \>
<blink>four</blink>"""
self.assertEqual(lyrics._scrape_strip_cruft(text, True),
"one\ntwo !\n\nfour")
def test_scrape_merge_paragraphs(self):
text = u"one</p> <p class='myclass'>two</p><p>three"
self.assertEqual(lyrics._scrape_merge_paragraphs(text),
"one\ntwo\nthree")
LYRICS_TEXTS = confit.load_yaml(os.path.join(_common.RSRC, 'lyricstext.yaml'))
definfo = dict(artist=u'The Beatles', title=u'Lady Madonna') # default query
class MockFetchUrl(object):
def __init__(self, pathval='fetched_path'):
self.pathval = pathval
self.fetched = None
def __call__(self, url, filename=None):
self.fetched = url
url = url.replace('http://', '').replace('www.', '')
fn = "".join(x for x in url if (x.isalnum() or x == '/'))
fn = fn.split('/')
fn = os.path.join('rsrc', 'lyrics', fn[0], fn[-1]) + '.txt'
with open(fn, 'r') as f:
content = f.read()
return content
def is_lyrics_content_ok(title, text):
"""Compare lyrics text to expected lyrics for given title"""
setexpected = set(LYRICS_TEXTS[lyrics.slugify(title)].split())
settext = set(text.split())
setinter = setexpected.intersection(settext)
# consider lyrics ok if they share 50% or more with the reference
if len(setinter):
ratio = 1.0 * max(len(setexpected), len(settext)) / len(setinter)
return (ratio > .5 and ratio < 2.5)
return False
class LyricsGooglePluginTest(unittest.TestCase):
# Every source entered in default beets google custom search engine
# must be listed below.
# Use default query when possible, or override artist and title field
# if website don't have lyrics for default query.
sourcesOk = [
dict(definfo,
url=u'http://www.absolutelyrics.com',
path=u'/lyrics/view/the_beatles/lady_madonna'),
dict(definfo,
url=u'http://www.azlyrics.com',
path=u'/lyrics/beatles/ladymadonna.html'),
dict(definfo,
url=u'http://www.chartlyrics.com',
path=u'/_LsLsZ7P4EK-F-LD4dJgDQ/Lady+Madonna.aspx'),
dict(definfo,
url=u'http://www.elyricsworld.com',
path=u'/lady_madonna_lyrics_beatles.html'),
dict(definfo,
url=u'http://www.lacoccinelle.net',
artist=u'Jacques Brel', title=u"Amsterdam",
path=u'/paroles-officielles/275679.html'),
dict(definfo,
url=u'http://www.lyrics007.com',
path=u'/The%20Beatles%20Lyrics/Lady%20Madonna%20Lyrics.html'),
dict(definfo,
url='http://www.lyrics.com/',
path=u'lady-madonna-lyrics-the-beatles.html'),
dict(definfo,
url='http://www.lyricsmania.com/',
path='lady_madonna_lyrics_the_beatles.html'),
dict(definfo,
url=u'http://www.lyrics.net',
path=u'/lyric/17547916'),
dict(definfo,
url=u'http://www.lyricsontop.com',
artist=u'Amy Winehouse', title=u"Jazz'n'blues",
path=u'/amy-winehouse-songs/jazz-n-blues-lyrics.html'),
dict(definfo,
url=u'http://lyrics.wikia.com/',
path=u'The_Beatles:Lady_Madonna'),
dict(definfo,
url='http://www.metrolyrics.com/',
path='lady-madonna-lyrics-beatles.html'),
dict(definfo,
url=u'http://www.paroles.net/',
artist=u'Lilly Wood & the prick', title=u"Hey it's ok",
path=u'lilly-wood-the-prick/paroles-hey-it-s-ok'),
dict(definfo,
url=u'http://www.reggaelyrics.info',
artist=u'Beres Hammond', title=u'I could beat myself',
path=u'/beres-hammond/i-could-beat-myself'),
dict(definfo,
url='http://www.releaselyrics.com',
path=u'/e35f/the-beatles-lady-madonna'),
dict(definfo,
url=u'http://www.smartlyrics.com',
path=u'/Song18148-The-Beatles-Lady-Madonna-lyrics.aspx'),
dict(definfo,
url='http://www.songlyrics.com',
path=u'/the-beatles/lady-madonna-lyrics'),
dict(definfo,
url=u'http://www.stlyrics.com',
path=u'/songs/r/richiehavens48961/ladymadonna2069109.html'),
dict(definfo,
url=u'http://www.sweetslyrics.com',
path=u'/761696.The%20Beatles%20-%20Lady%20Madonna.html')]
def setUp(self):
"""Set up configuration"""
try:
__import__('bs4')
except ImportError:
self.skipTest('Beautiful Soup 4 not available')
lyrics.LyricsPlugin()
lyrics.fetch_url = MockFetchUrl()
def test_default_ok(self):
"""Test each lyrics engine with the default query"""
for f in (lyrics.fetch_lyricswiki, lyrics.fetch_lyricscom):
res = f(definfo['artist'], definfo['title'])
self.assertTrue(lyrics.is_lyrics(res))
self.assertTrue(is_lyrics_content_ok(definfo['title'], res))
def test_missing_lyrics(self):
self.assertFalse(lyrics.is_lyrics(LYRICS_TEXTS['missing_texts']))
def test_sources_ok(self):
for s in self.sourcesOk:
url = s['url'] + s['path']
res = lyrics.scrape_lyrics_from_html(lyrics.fetch_url(url))
self.assertTrue(lyrics.is_lyrics(res), url)
self.assertTrue(is_lyrics_content_ok(s['title'], res), url)
def test_is_page_candidate(self):
from bs4 import SoupStrainer, BeautifulSoup
for s in self.sourcesOk:
url = unicode(s['url'] + s['path'])
html = lyrics.fetch_url(url)
soup = BeautifulSoup(html, "html.parser",
parse_only=SoupStrainer('title'))
self.assertEqual(lyrics.is_page_candidate(url, soup.title.string,
s['title'], s['artist']),
True, url)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -14,16 +14,17 @@
from mock import patch
from _common import unittest
from helper import TestHelper
import helper
from beets import plugins
from beets.library import Item
from beets.dbcore import types
from beets.mediafile import MediaFile
class PluginTest(unittest.TestCase, TestHelper):
class TestHelper(helper.TestHelper):
def setUp(self):
def setup_plugin_loader(self):
# FIXME the mocking code is horrific, but this is the lowest and
# earliest level of the plugin mechanism we can hook into.
self._plugin_loader_patch = patch('beets.plugins.load_plugins')
@ -35,9 +36,22 @@ class PluginTest(unittest.TestCase, TestHelper):
load_plugins.side_effect = myload
self.setup_beets()
def tearDown(self):
def teardown_plugin_loader(self):
self._plugin_loader_patch.stop()
self.unload_plugins()
def register_plugin(self, plugin_class):
self._plugin_classes.add(plugin_class)
class ItemTypesTest(unittest.TestCase, TestHelper):
def setUp(self):
self.setup_plugin_loader()
self.setup_beets()
def tearDown(self):
self.teardown_plugin_loader()
self.teardown_beets()
def test_flex_field_type(self):
@ -64,8 +78,38 @@ class PluginTest(unittest.TestCase, TestHelper):
out = self.run_with_output('ls', 'rating:3..5')
self.assertNotIn('aaa', out)
def register_plugin(self, plugin_class):
self._plugin_classes.add(plugin_class)
class ItemWriteTest(unittest.TestCase, TestHelper):
def setUp(self):
self.setup_plugin_loader()
self.setup_beets()
class EventListenerPlugin(plugins.BeetsPlugin):
pass
self.event_listener_plugin = EventListenerPlugin
self.register_plugin(EventListenerPlugin)
def tearDown(self):
self.teardown_plugin_loader()
self.teardown_beets()
def test_change_tags(self):
def on_write(item=None, path=None, tags=None):
if tags['artist'] == 'XXX':
tags['artist'] = 'YYY'
self.register_listener('write', on_write)
item = self.add_item_fixture(artist='XXX')
item.write()
mediafile = MediaFile(item.path)
self.assertEqual(mediafile.artist, 'YYY')
def register_listener(self, event, func):
self.event_listener_plugin.register_listener(event, func)
def suite():

View file

@ -16,14 +16,26 @@
"""
import _common
from _common import unittest
from helper import TestHelper
import helper
import beets.library
from beets import dbcore
from beets.dbcore import types
from beets.dbcore.query import NoneQuery
from beets.library import Library, Item
class TestHelper(helper.TestHelper):
def assertInResult(self, item, results):
result_ids = map(lambda i: i.id, results)
self.assertIn(item.id, result_ids)
def assertNotInResult(self, item, results):
result_ids = map(lambda i: i.id, results)
self.assertNotIn(item.id, result_ids)
class AnyFieldQueryTest(_common.LibTestCase):
def test_no_restriction(self):
q = dbcore.query.AnyFieldQuery(
@ -383,6 +395,9 @@ class IntQueryTest(unittest.TestCase, TestHelper):
def setUp(self):
self.lib = Library(':memory:')
def tearDown(self):
Item._types = {}
def test_exact_value_match(self):
item = self.add_item(bpm=120)
matched = self.lib.items('bpm:120').get()
@ -414,6 +429,59 @@ class IntQueryTest(unittest.TestCase, TestHelper):
self.assertIsNone(matched)
class BoolQueryTest(unittest.TestCase, TestHelper):
def setUp(self):
self.lib = Library(':memory:')
Item._types = {'flexbool': types.Boolean()}
def tearDown(self):
Item._types = {}
def test_parse_true(self):
item_true = self.add_item(comp=True)
item_false = self.add_item(comp=False)
matched = self.lib.items('comp:true')
self.assertInResult(item_true, matched)
self.assertNotInResult(item_false, matched)
def test_flex_parse_true(self):
item_true = self.add_item(flexbool=True)
item_false = self.add_item(flexbool=False)
matched = self.lib.items('flexbool:true')
self.assertInResult(item_true, matched)
self.assertNotInResult(item_false, matched)
def test_flex_parse_false(self):
item_true = self.add_item(flexbool=True)
item_false = self.add_item(flexbool=False)
matched = self.lib.items('flexbool:false')
self.assertInResult(item_false, matched)
self.assertNotInResult(item_true, matched)
def test_flex_parse_1(self):
item_true = self.add_item(flexbool=True)
item_false = self.add_item(flexbool=False)
matched = self.lib.items('flexbool:1')
self.assertInResult(item_true, matched)
self.assertNotInResult(item_false, matched)
def test_flex_parse_0(self):
item_true = self.add_item(flexbool=True)
item_false = self.add_item(flexbool=False)
matched = self.lib.items('flexbool:0')
self.assertInResult(item_false, matched)
self.assertNotInResult(item_true, matched)
def test_flex_parse_any_string(self):
# TODO this should be the other way around
item_true = self.add_item(flexbool=True)
item_false = self.add_item(flexbool=False)
matched = self.lib.items('flexbool:something')
self.assertInResult(item_false, matched)
self.assertNotInResult(item_true, matched)
class DefaultSearchFieldsTest(DummyDataTestCase):
def test_albums_matches_album(self):
albums = list(self.lib.albums('baz'))
@ -432,6 +500,30 @@ class DefaultSearchFieldsTest(DummyDataTestCase):
self.assert_matched(items, [])
class NoneQueryTest(unittest.TestCase, TestHelper):
def setUp(self):
self.lib = Library(':memory:')
def test_match_singletons(self):
singleton = self.add_item()
album_item = self.add_album().items().get()
matched = self.lib.items(NoneQuery('album_id'))
self.assertInResult(singleton, matched)
self.assertNotInResult(album_item, matched)
def test_match_after_set_none(self):
item = self.add_item(rg_track_gain=0)
matched = self.lib.items(NoneQuery('rg_track_gain'))
self.assertNotInResult(item, matched)
item['rg_track_gain'] = None
item.store()
matched = self.lib.items(NoneQuery('rg_track_gain'))
self.assertInResult(item, matched)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -1,5 +1,5 @@
# This file is part of beets.
# Copyright 2013, Adrian Sampson.
# Copyright 2014, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@ -18,6 +18,7 @@ import _common
from _common import unittest
import beets.library
from beets import dbcore
from beets import config
# A test case class providing a library with some dummy data and some
@ -33,16 +34,22 @@ class DummyDataTestCase(_common.TestCase):
albums[0].year = "2001"
albums[0].flex1 = "flex1-1"
albums[0].flex2 = "flex2-A"
albums[0].albumartist = "foo"
albums[0].albumartist_sort = None
albums[1].album = "album B"
albums[1].genre = "Rock"
albums[1].year = "2001"
albums[1].flex1 = "flex1-2"
albums[1].flex2 = "flex2-A"
albums[1].albumartist = "bar"
albums[1].albumartist_sort = None
albums[2].album = "album C"
albums[2].genre = "Jazz"
albums[2].year = "2005"
albums[2].flex1 = "flex1-1"
albums[2].flex2 = "flex2-B"
albums[2].albumartist = "baz"
albums[2].albumartist_sort = None
for album in albums:
self.lib.add(album)
@ -55,6 +62,7 @@ class DummyDataTestCase(_common.TestCase):
items[0].flex1 = "flex1-0"
items[0].flex2 = "flex2-A"
items[0].album_id = albums[0].id
items[0].artist_sort = None
items[1].title = 'baz qux'
items[1].artist = 'two'
items[1].album = 'baz'
@ -63,6 +71,7 @@ class DummyDataTestCase(_common.TestCase):
items[1].flex1 = "flex1-1"
items[1].flex2 = "flex2-A"
items[1].album_id = albums[0].id
items[1].artist_sort = None
items[2].title = 'beets 4 eva'
items[2].artist = 'three'
items[2].album = 'foo'
@ -71,6 +80,7 @@ class DummyDataTestCase(_common.TestCase):
items[2].flex1 = "flex1-2"
items[2].flex2 = "flex1-B"
items[2].album_id = albums[1].id
items[2].artist_sort = None
items[3].title = 'beets 4 eva'
items[3].artist = 'three'
items[3].album = 'foo2'
@ -79,6 +89,7 @@ class DummyDataTestCase(_common.TestCase):
items[3].flex1 = "flex1-2"
items[3].flex2 = "flex1-C"
items[3].album_id = albums[2].id
items[3].artist_sort = None
for item in items:
self.lib.add(item)
@ -324,6 +335,26 @@ class SortCombinedFieldTest(DummyDataTestCase):
self.assertEqual(r1.id, r2.id)
class ConfigSortTest(DummyDataTestCase):
def test_default_sort_item(self):
results = list(self.lib.items())
self.assertLess(results[0].artist, results[1].artist)
def test_config_opposite_sort_item(self):
config['sort_item'] = 'artist-'
results = list(self.lib.items())
self.assertGreater(results[0].artist, results[1].artist)
def test_default_sort_album(self):
results = list(self.lib.albums())
self.assertLess(results[0].albumartist, results[1].albumartist)
def test_config_opposite_sort_album(self):
config['sort_album'] = 'albumartist-'
results = list(self.lib.albums())
self.assertGreater(results[0].albumartist, results[1].albumartist)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -7,6 +7,7 @@ from beets import config
from beets.library import Item
from beetsplug import spotify
from helper import TestHelper
import urlparse
class ArgumentsMock(object):
@ -16,6 +17,11 @@ class ArgumentsMock(object):
self.verbose = True
def _params(url):
"""Get the query parameters from a URL."""
return urlparse.parse_qs(urlparse.urlparse(url).query)
class SpotifyPluginTest(_common.TestCase, TestHelper):
def setUp(self):
@ -37,6 +43,7 @@ class SpotifyPluginTest(_common.TestCase, TestHelper):
def test_empty_query(self):
self.assertEqual(None, self.spotify.query_spotify(self.lib, "1=2"))
@responses.activate
def test_missing_request(self):
response_body = str(
'{'
@ -52,9 +59,7 @@ class SpotifyPluginTest(_common.TestCase, TestHelper):
'}'
'}'
)
responses.add(responses.GET,
'https://api.spotify.com/v1/search?q=duifhjslkef+album'
'%3Alkajsdflakjsd+artist%3A&type=track',
responses.add(responses.GET, 'https://api.spotify.com/v1/search',
body=response_body, status=200,
content_type='application/json')
item = Item(
@ -67,6 +72,14 @@ class SpotifyPluginTest(_common.TestCase, TestHelper):
item.add(self.lib)
self.assertEquals([], self.spotify.query_spotify(self.lib, ""))
params = _params(responses.calls[0].request.url)
self.assertEquals(
params['q'],
['duifhjslkef album:lkajsdflakjsd artist:ujydfsuihse'],
)
self.assertEquals(params['type'], ['track'])
@responses.activate
def test_track_request(self):
response_body = str(
'{'
@ -164,10 +177,7 @@ class SpotifyPluginTest(_common.TestCase, TestHelper):
'}'
'}'
)
responses.add(responses.GET,
'https://api.spotify.com/v1/search?q=Happy+album%3A'
'Despicable%20Me%202+artist%3APharrell%20'
'Williams&type=track',
responses.add(responses.GET, 'https://api.spotify.com/v1/search',
body=response_body, status=200,
content_type='application/json')
item = Item(
@ -183,6 +193,13 @@ class SpotifyPluginTest(_common.TestCase, TestHelper):
self.assertEquals("6NPVjNh8Jhru9xOmyQigds", results[0]['id'])
self.spotify.output_results(results)
params = _params(responses.calls[0].request.url)
self.assertEquals(
params['q'],
['Happy album:Despicable Me 2 artist:Pharrell Williams'],
)
self.assertEquals(params['type'], ['track'])
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -145,7 +145,8 @@ class ModifyTest(unittest.TestCase, TestHelper):
def setUp(self):
self.setup_beets()
self.add_album_fixture()
self.album = self.add_album_fixture()
[self.item] = self.album.items()
def tearDown(self):
self.teardown_beets()
@ -183,6 +184,22 @@ class ModifyTest(unittest.TestCase, TestHelper):
item = self.lib.items().get()
self.assertNotIn('newTitle', item.path)
def test_update_mtime(self):
item = self.item
old_mtime = item.mtime
self.modify("title=newTitle")
item.load()
self.assertNotEqual(old_mtime, item.mtime)
self.assertEqual(item.current_mtime(), item.mtime)
def test_reset_mtime_with_no_write(self):
item = self.item
self.modify("--nowrite", "title=newTitle")
item.load()
self.assertEqual(0, item.mtime)
# Album Tests
def test_modify_album(self):
@ -275,6 +292,30 @@ class ModifyTest(unittest.TestCase, TestHelper):
self.assertEqual(mods, {"title": "newTitle"})
class WriteTest(unittest.TestCase, TestHelper):
def setUp(self):
self.setup_beets()
def tearDown(self):
self.teardown_beets()
def write_cmd(self, *args):
ui._raw_main(['write'] + list(args), self.lib)
def test_update_mtime(self):
item = self.add_item_fixture()
item['title'] = 'a new title'
item.store()
item = self.lib.items().get()
self.assertEqual(item.mtime, 0)
self.write_cmd()
item = self.lib.items().get()
self.assertEqual(item.mtime, item.current_mtime())
class MoveTest(_common.TestCase):
def setUp(self):
super(MoveTest, self).setUp()

View file

@ -18,37 +18,38 @@ class ZeroPluginTest(unittest.TestCase, TestHelper):
self.unload_plugins()
def test_no_patterns(self):
i = Item(
comments='test comment',
day=13,
month=3,
year=2012,
)
tags = {
'comments': 'test comment',
'day': 13,
'month': 3,
'year': 2012,
}
z = ZeroPlugin()
z.debug = False
z.fields = ['comments', 'month', 'day']
z.patterns = {'comments': ['.'],
'month': ['.'],
'day': ['.']}
z.write_event(i)
self.assertEqual(i.comments, '')
self.assertEqual(i.day, 0)
self.assertEqual(i.month, 0)
self.assertEqual(i.year, 2012)
z.write_event(None, None, tags)
self.assertEqual(tags['comments'], None)
self.assertEqual(tags['day'], None)
self.assertEqual(tags['month'], None)
self.assertEqual(tags['year'], 2012)
def test_patterns(self):
i = Item(
comments='from lame collection, ripped by eac',
year=2012,
)
z = ZeroPlugin()
z.debug = False
z.fields = ['comments', 'year']
z.patterns = {'comments': 'eac lame'.split(),
'year': '2098 2099'.split()}
z.write_event(i)
self.assertEqual(i.comments, '')
self.assertEqual(i.year, 2012)
tags = {
'comments': 'from lame collection, ripped by eac',
'year': 2012,
}
z.write_event(None, None, tags)
self.assertEqual(tags['comments'], None)
self.assertEqual(tags['year'], 2012)
def test_delete_replaygain_tag(self):
path = self.create_mediafile_fixture()
@ -70,6 +71,17 @@ class ZeroPluginTest(unittest.TestCase, TestHelper):
self.assertIsNone(mediafile.rg_track_peak)
self.assertIsNone(mediafile.rg_track_gain)
def test_do_not_change_database(self):
item = self.add_item_fixture(year=2000)
mediafile = MediaFile(item.path)
config['zero'] = {'fields': ['year']}
self.load_plugins('zero')
item.write()
self.assertEqual(item['year'], 2000)
self.assertIsNone(mediafile.year)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)