text:
from __future__ import unicode_literals

import re
import itertools

from .common import InfoExtractor
from ..utils import (
    clean_html,
    dict_get,
    ExtractorError,
    float_or_none,
    get_element_by_class,
    int_or_none,
    parse_duration,
    parse_iso8601,
    try_get,
    unescapeHTML,
    urlencode_postdata,
    urljoin,
)
from ..compat import (
    compat_etree_fromstring,
    compat_HTTPError,
    compat_urlparse,
)

class BBCCoUkIE(InfoExtractor):
    IE_NAME = 'bbc.co.uk'
    IE_DESC = 'BBC iPlayer'
    _ID_REGEX = r'[pb][\da-z]{7}'
    _VALID_URL = r'''(?x)
                    https?://
                        (?:www\.)?bbc\.co\.uk/
                        (?:
                            programmes/(?!articles/)|
                            iplayer(?:/[^/]+)?/(?:episode/|playlist/)|
                            music/(?:clips|audiovideo/popular)[/#]|
                            radio/player/
                        )
                        (?P<id>%s)(?!/(?:episodes|broadcasts|clips))
                    ''' % _ID_REGEX

    _LOGIN_URL = 'https://account.bbc.com/signin'
    _NETRC_MACHINE = 'bbc'

    _MEDIASELECTOR_URLS = [
        # Provides HQ HLS streams with even better quality that pc mediaset but fails
        # with geolocation in some cases when it's even not geo restricted at all (e.g.
        # http://www.bbc.co.uk/programmes/b06bp7lf). Also may fail with selectionunavailable.
        'http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/iptv-all/vpid/%s',
        'http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/pc/vpid/%s',
    ]

    _MEDIASELECTION_NS = 'http://bbc.co.uk/2008/mp/mediaselection'
    _EMP_PLAYLIST_NS = 'http://bbc.co.uk/2008/emp/playlist'

    _NAMESPACES = (
        _MEDIASELECTION_NS,
        _EMP_PLAYLIST_NS,
    )

    _TESTS = [
        {
            'url': 'http://www.bbc.co.uk/programmes/b039g8p7',
            'info_dict': {
                'id': 'b039d07m',
                'ext': 'flv',
                'title': 'Leonard Cohen, Kaleidoscope - BBC Radio 4',
                'description': 'The Canadian poet and songwriter reflects on his musical career.',
            },
            'params': {
                # rtmp download
                'skip_download': True,
            }
        },
        {
            'url': 'http://www.bbc.co.uk/iplayer/episode/b00yng5w/The_Man_in_Black_Series_3_The_Printed_Name/',
            'info_dict': {
                'id': 'b00yng1d',
                'ext': 'flv',
                'title': 'The Man in Black: Series 3: The Printed Name',
                'description': "Mark Gatiss introduces Nicholas Pierpan's chilling tale of a writer's devilish pact with a mysterious man. Stars Ewan Bailey.",
                'duration': 1800,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'Episode is no longer available on BBC iPlayer Radio',
        },
        {
            'url': 'http://www.bbc.co.uk/iplayer/episode/b03vhd1f/The_Voice_UK_Series_3_Blind_Auditions_5/',
            'info_dict': {
                'id': 'b00yng1d',
                'ext': 'flv',
                'title': 'The Voice UK: Series 3: Blind Auditions 5',
                'description': 'Emma Willis and Marvin Humes present the fifth set of blind auditions in the singing competition, as the coaches continue to build their teams based on voice alone.',
                'duration': 5100,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'Currently BBC iPlayer TV programmes are available to play in the UK only',
        },
        {
            'url': 'http://www.bbc.co.uk/iplayer/episode/p026c7jt/tomorrows-worlds-the-unearthly-history-of-science-fiction-2-invasion',
            'info_dict': {
                'id': 'b03k3pb7',
                'ext': 'flv',
                'title': "Tomorrow's Worlds: The Unearthly History of Science Fiction",
                'description': '2. Invasion',
                'duration': 3600,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'Currently BBC iPlayer TV programmes are available to play in the UK only',
        }, {
            'url': 'http://www.bbc.co.uk/programmes/b04v20dw',
            'info_dict': {
                'id': 'b04v209v',
                'ext': 'flv',
                'title': 'Pete Tong, The Essential New Tune Special',
                'description': "Pete has a very special mix - all of 2014's Essential New Tunes!",
                'duration': 10800,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'Episode is no longer available on BBC iPlayer Radio',
        }, {
            'url': 'http://www.bbc.co.uk/music/clips/p022h44b',
            'note': 'Audio',
            'info_dict': {
                'id': 'p022h44j',
                'ext': 'flv',
                'title': 'BBC Proms Music Guides, Rachmaninov: Symphonic Dances',
                'description': "In this Proms Music Guide, Andrew McGregor looks at Rachmaninov's Symphonic Dances.",
                'duration': 227,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            }
        }, {
            'url': 'http://www.bbc.co.uk/music/clips/p025c0zz',
            'note': 'Video',
            'info_dict': {
                'id': 'p025c103',
                'ext': 'flv',
                'title': 'Reading and Leeds Festival, 2014, Rae Morris - Closer (Live on BBC Three)',
                'description': 'Rae Morris performs Closer for BBC Three at Reading 2014',
                'duration': 226,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            }
        }, {
            'url': 'http://www.bbc.co.uk/iplayer/episode/b054fn09/ad/natural-world-20152016-2-super-powered-owls',
            'info_dict': {
                'id': 'p02n76xf',
                'ext': 'flv',
                'title': 'Natural World, 2015-2016: 2. Super Powered Owls',
                'description': 'md5:e4db5c937d0e95a7c6b5e654d429183d',
                'duration': 3540,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'geolocation',
        }, {
            'url': 'http://www.bbc.co.uk/iplayer/episode/b05zmgwn/royal-academy-summer-exhibition',
            'info_dict': {
                'id': 'b05zmgw1',
                'ext': 'flv',
                'description': 'Kirsty Wark and Morgan Quaintance visit the Royal Academy as it prepares for its annual artistic extravaganza, meeting people who have come together to make the show unique.',
                'title': 'Royal Academy Summer Exhibition',
                'duration': 3540,
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'geolocation',
        }, {
            # iptv-all mediaset fails with geolocation however there is no geo restriction
            # for this programme at all
            'url': 'http://www.bbc.co.uk/programmes/b06rkn85',
            'info_dict': {
                'id': 'b06rkms3',
                'ext': 'flv',
                'title': "Best of the Mini-Mixes 2015: Part 3, Annie Mac's Friday Night - BBC Radio 1",
                'description': "Annie has part three in the Best of the Mini-Mixes 2015, plus the year's Most Played!",
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
            'skip': 'Now it\'s really geo-restricted',
        }, {
            # compact player (https://github.com/rg3/youtube-dl/issues/8147)
            'url': 'http://www.bbc.co.uk/programmes/p028bfkf/player',
            'info_dict': {
                'id': 'p028bfkj',
                'ext': 'flv',
                'title': 'Extract from BBC documentary Look Stranger - Giant Leeks and Magic Brews',
                'description': 'Extract from BBC documentary Look Stranger - Giant Leeks and Magic Brews',
            },
            'params': {
                # rtmp download
                'skip_download': True,
            },
        }, {
            'url': 'http://www.bbc.co.uk/iplayer/playlist/p01dvks4',
            'only_matching': True,
        }, {
            'url': 'http://www.bbc.co.uk/music/clips#p02frcc3',
            'only_matching': True,
        }, {
            'url': 'http://www.bbc.co.uk/iplayer/cbeebies/episode/b0480276/bing-14-atchoo',
            'only_matching': True,
        }, {
            'url': 'http://www.bbc.co.uk/radio/player/p03cchwf',
            'only_matching': True,
        }, {
            'url': 'https://www.bbc.co.uk/music/audiovideo/popular#p055bc55',
            'only_matching': True,
        }]

    _USP_RE = r'/([^/]+?)\.ism(?:\.hlsv2\.ism)?/[^/]+\.m3u8'

    def _login(self):
        username, password = self._get_login_info()
        if username is None:
            return

        login_page = self._download_webpage(
            self._LOGIN_URL, None, 'Downloading signin page')

        login_form = self._hidden_inputs(login_page)

        login_form.update({
            'username': username,
            'password': password,
        })

        post_url = urljoin(self._LOGIN_URL, self._search_regex(
            r'<form[^>]+action=(["\'])(?P<url>.+?)\1', login_page,
            'post url', default=self._LOGIN_URL, group='url'))

        response, urlh = self._download_webpage_handle(
            post_url, None, 'Logging in', data=urlencode_postdata(login_form),
            headers={'Referer': self._LOGIN_URL})

        if self._LOGIN_URL in urlh.geturl():
            error = clean_html(get_element_by_class('form-message', response))
            if error:
                raise ExtractorError(
                    'Unable to login: %s' % error, expected=True)
            raise ExtractorError('Unable to log in')

    def _real_initialize(self):
        self._login()

    class MediaSelectionError(Exception):
        def __init__(self, id):
            self.id = id

    def _extract_asx_playlist(self, connection, programme_id):
        asx = self._download_xml(connection.get('href'), programme_id, 'Downloading ASX playlist')
        return [ref.get('href') for ref in asx.findall('./Entry/ref')]

    def _extract_items(self, playlist):
        return playlist.findall('./{%s}item' % self._EMP_PLAYLIST_NS)

    def _findall_ns(self, element, xpath):
        elements = []
        for ns in self._NAMESPACES:
            elements.extend(element.findall(xpath % ns))
        return elements

    def _extract_medias(self, media_selection):
        error = media_selection.find('./{%s}error' % self._MEDIASELECTION_NS)
        if error is None:
            media_selection.find('./{%s}error' % self._EMP_PLAYLIST_NS)
        if error is not None:
            raise BBCCoUkIE.MediaSelectionError(error.get('id'))
        return self._findall_ns(media_selection, './{%s}media')

    def _extract_connections(self, media):
        return self._findall_ns(media, './{%s}connection')

    def _get_subtitles(self, media, programme_id):
        subtitles = {}
        for connection in self._extract_connections(media):
            captions = self._download_xml(connection.get('href'), programme_id, 'Downloading captions')
            lang = captions.get('{http://www.w3.org/XML/1998/namespace}lang', 'en')
            subtitles[lang] = [
                {
                    'url': connection.get('href'),
                    'ext': 'ttml',
                },
            ]
        return subtitles

    def _raise_extractor_error(self, media_selection_error):
        raise ExtractorError(
            '%s returned error: %s' % (self.IE_NAME, media_selection_error.id),
            expected=True)

    def _download_media_selector(self, programme_id):
        last_exception = None
        for mediaselector_url in self._MEDIASELECTOR_URLS:
            try:
                return self._download_media_selector_url(
                    mediaselector_url % programme_id, programme_id)
            except BBCCoUkIE.MediaSelectionError as e:
                if e.id in ('notukerror', 'geolocation', 'selectionunavailable'):
                    last_exception = e
                    continue
                self._raise_extractor_error(e)
        self._raise_extractor_error(last_exception)

    def _download_media_selector_url(self, url, programme_id=None):
        try:
            media_selection = self._download_xml(
                url, programme_id, 'Downloading media selection XML')
        except ExtractorError as ee:
            if isinstance(ee.cause, compat_HTTPError) and ee.cause.code in (403, 404):
                media_selection = compat_etree_fromstring(ee.cause.read().decode('utf-8'))
            else:
                raise
        return self._process_media_selector(media_selection, programme_id)

    def _process_media_selector(self, media_selection, programme_id):
        formats = []
        subtitles = None
        urls = []

        for media in self._extract_medias(media_selection):
            kind = media.get('kind')
            if kind in ('video', 'audio'):
                bitrate = int_or_none(media.get('bitrate'))
                encoding = media.get('encoding')
                service = media.get('service')
                width = int_or_none(media.get('width'))
                height = int_or_none(media.get('height'))
                file_size = int_or_none(media.get('media_file_size'))
                for connection in self._extract_connections(media):
                    href = connection.get('href')
                    if href in urls:
                        continue
                    if href:
                        urls.append(href)
                    conn_kind = connection.get('kind')
                    protocol = connection.get('protocol')
                    supplier = connection.get('supplier')
                    transfer_format = connection.get('transferFormat')
                    format_id = supplier or conn_kind or protocol
                    if service:
                        format_id = '%s_%s' % (service, format_id)
                    # ASX playlist
                    if supplier == 'asx':
                        for i, ref in enumerate(self._extract_asx_playlist(connection, programme_id)):
                            formats.append({
                                'url': ref,
                                'format_id': 'ref%s_%s' % (i, format_id),
                            })
                    elif transfer_format == 'dash':
                        formats.extend(self._extract_mpd_formats(
                            href, programme_id, mpd_id=format_id, fatal=False))
                    elif transfer_format == 'hls':
                        formats.extend(self._extract_m3u8_formats(
                            href, programme_id, ext='mp4', entry_protocol='m3u8_native',
                            m3u8_id=format_id, fatal=False))
                        if re.search(self._USP_RE, href):
                            usp_formats = self._extract_m3u8_formats(
                                re.sub(self._USP_RE, r'/\1.ism/\1.m3u8', href),
                                programme_id, ext='mp4', entry_protocol='m3u8_native',
                                m3u8_id=format_id, fatal=False)
                            for f in usp_formats:
                                if f.get('height') and f['height'] > 720:
                                    continue
                                formats.append(f)
                    elif transfer_format == 'hds':
                        formats.extend(self._extract_f4m_formats(
                            href, programme_id, f4m_id=format_id, fatal=False))
                    else:
                        if not service and not supplier and bitrate:
                            format_id += '-%d' % bitrate
                        fmt = {
                            'format_id': format_id,
                            'filesize': file_size,
                        }
                        if kind == 'video':
                            fmt.update({
                                'width': width,
                                'height': height,
                                'tbr': bitrate,
                                'vcodec': encoding,
                            })
                        else:
                            fmt.update({
                                'abr': bitrate,
                                'acodec': encoding,
                                'vcodec': 'none',
                            })
                        if protocol in ('http', 'https'):
                            # Direct link
                            fmt.update({
                                'url': href,
                            })
                        elif protocol == 'rtmp':
                            application = connection.get('application', 'ondemand')
                            auth_string = connection.get('authString')
                            identifier = connection.get('identifier')
                            server = connection.get('server')
                            fmt.update({
                                'url': '%s://%s/%s?%s' % (protocol, server, application, auth_string),
                                'play_path': identifier,
                                'app': '%s?%s' % (application, auth_string),
                                'page_url': 'http://www.bbc.co.uk',
                                'player_url': 'http://www.bbc.co.uk/emp/releases/iplayer/revisions/617463_618125_4/617463_618125_4_emp.swf',
                                'rtmp_live': False,
                                'ext': 'flv',
                            })
                        else:
                            continue
                        formats.append(fmt)
            elif kind == 'captions':
                subtitles = self.extract_subtitles(media, programme_id)
        return formats, subtitles

    def _download_playlist(self, playlist_id):
        try:
            playlist = self._download_json(
                'http://www.bbc.co.uk/programmes/%s/playlist.json' % playlist_id,
                playlist_id, 'Downloading playlist JSON')

            version = playlist.get('defaultAvailableVersion')
            if version:
                smp_config = version['smpConfig']
                title = smp_config['title']
                description = smp_config['summary']
                for item in smp_config['items']:
                    kind = item['kind']
                    if kind not in ('programme', 'radioProgramme'):
                        continue
                    programme_id = item.get('vpid')
                    duration = int_or_none(item.get('duration'))
                    formats, subtitles = self._download_media_selector(programme_id)
                return programme_id, title, description, duration, formats, subtitles
        except ExtractorError as ee:
            if not (isinstance(ee.cause, compat_HTTPError) and ee.cause.code == 404):
                raise

        # fallback to legacy playlist
        return self._process_legacy_playlist(playlist_id)

    def _process_legacy_playlist_url(self, url, display_id):
        playlist = self._download_legacy_playlist_url(url, display_id)
        return self._extract_from_legacy_playlist(playlist, display_id)

    def _process_legacy_playlist(self, playlist_id):
        return self._process_legacy_playlist_url(
            'http://www.bbc.co.uk/iplayer/playlist/%s' % playlist_id, playlist_id)

    def _download_legacy_playlist_url(self, url, playlist_id=None):
        return self._download_xml(
            url, playlist_id, 'Downloading legacy playlist XML')

    def _extract_from_legacy_playlist(self, playlist, playlist_id):
        no_items = playlist.find('./{%s}noItems' % self._EMP_PLAYLIST_NS)
        if no_items is not None:
            reason = no_items.get('reason')
            if reason == 'preAvailability':
                msg = 'Episode %s is not yet available' % playlist_id
            elif reason == 'postAvailability':
                msg = 'Episode %s is no longer available' % playlist_id
            elif reason == 'noMedia':
                msg = 'Episode %s is not currently available' % playlist_id
            else:
                msg = 'Episode %s is not available: %s' % (playlist_id, reason)
            raise ExtractorError(msg, expected=True)

        for item in self._extract_items(playlist):
            kind = item.get('kind')
            if kind not in ('programme', 'radioProgramme'):
                continue
            title = playlist.find('./{%s}title' % self._EMP_PLAYLIST_NS).text
            description_el = playlist.find('./{%s}summary' % self._EMP_PLAYLIST_NS)
            description = description_el.text if description_el is not None else None

            def get_programme_id(item):
                def get_from_attributes(item):
                    for p in('identifier', 'group'):
                        value = item.get(p)
                        if value and re.match(r'^[pb][\da-z]{7}$', value):
                            return value
                get_from_attributes(item)
                mediator = item.find('./{%s}mediator' % self._EMP_PLAYLIST_NS)
                if mediator is not None:
                    return get_from_attributes(mediator)

            programme_id = get_programme_id(item)
            duration = int_or_none(item.get('duration'))

            if programme_id:
                formats, subtitles = self._download_media_selector(programme_id)
            else:
                formats, subtitles = self._process_media_selector(item, playlist_id)
                programme_id = playlist_id

        return programme_id, title, description, duration, formats, subtitles

    def _real_extract(self, url):
        group_id = self._match_id(url)

        webpage = self._download_webpage(url, group_id, 'Downloading video page')

        error = self._search_regex(
            r'<div\b[^>]+\bclass=["\']smp__message delta["\'][^>]*>([^<]+)<',
            webpage, 'error', default=None)
        if error:
            raise ExtractorError(error, expected=True)

        programme_id = None
        duration = None

        tviplayer = self._search_regex(
            r'mediator\.bind\(({.+?})\s*,\s*document\.getElementById',
            webpage, 'player', default=None)

        if tviplayer:
            player = self._parse_json(tviplayer, group_id).get('player', {})
            duration = int_or_none(player.get('duration'))
            programme_id = player.get('vpid')

        if not programme_id:
            programme_id = self._search_regex(
                r'"vpid"\s*:\s*"(%s)"' % self._ID_REGEX, webpage, 'vpid', fatal=False, default=None)

        if programme_id:
            formats, subtitles = self._download_media_selector(programme_id)
            title = self._og_search_title(webpage, default=None) or self._html_search_regex(
                (r'<h2[^>]+id="parent-title"[^>]*>(.+?)</h2>',
                 r'<div[^>]+class="info"[^>]*>\s*<h1>(.+?)</h1>'), webpage, 'title')
            description = self._search_regex(
                (r'<p class="[^"]*medium-description[^"]*">([^<]+)</p>',
                 r'<div[^>]+class="info_+synopsis"[^>]*>([^<]+)</div>'),
                webpage, 'description', default=None)
            if not description:
                description = self._html_search_meta('description', webpage)
        else:
            programme_id, title, description, duration, formats, subtitles = self._download_playlist(group_id)

        self._sort_formats(formats)

        return {
            'id': programme_id,
            'title': title,
            'description': description,
            'thumbnail': self._og_search_thumbnail(webpage, default=None),
            'duration': duration,
            'formats': formats,
            'subtitles': subtitles,
        }

class BBCIE(BBCCoUkIE):
    IE_NAME = 'bbc'
    IE_DESC = 'BBC'
    _VALID_URL = r'https?://(?:www\.)?bbc\.(?:com|co\.uk)/(?:[^/]+/)+(?P<id>[^/#?]+)'

    _MEDIASELECTOR_URLS = [
        # Provides HQ HLS streams but fails with geolocation in some cases when it's
        # even not geo restricted at all
        'http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/iptv-all/vpid/%s',
        # Provides more formats, namely direct mp4 links, but fails on some videos with
        # notukerror for non UK (?) users (e.g.
        # http://www.bbc.com/travel/story/20150625-sri-lankas-spicy-secret)
        'http://open.live.bbc.co.uk/mediaselector/4/mtis/stream/%s',
        # Provides fewer formats, but works everywhere for everybody (hopefully)
        'http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/journalism-pc/vpid/%s',
    ]

    _TESTS = [{
        # article with multiple videos embedded with data-playable containing vpids
        'url': 'http://www.bbc.com/news/world-europe-32668511',
        'info_dict': {
            'id': 'world-europe-32668511',
            'title': 'Russia stages massive WW2 parade despite Western boycott',
            'description': 'md5:00ff61976f6081841f759a08bf78cc9c',
        },
        'playlist_count': 2,
    }, {
        # article with multiple videos embedded with data-playable (more videos)
        'url': 'http://www.bbc.com/news/business-28299555',
        'info_dict': {
            'id': 'business-28299555',
            'title': 'Farnborough Airshow: Video highlights',
            'description': 'BBC reports and video highlights at the Farnborough Airshow.',
        },
        'playlist_count': 9,
        'skip': 'Save time',
    }, {
        # article with multiple videos embedded with `new SMP()`
        # broken
        'url': 'http://www.bbc.co.uk/blogs/adamcurtis/entries/3662a707-0af9-3149-963f-47bea720b460',
        'info_dict': {
            'id': '3662a707-0af9-3149-963f-47bea720b460',
            'title': 'BUGGER',
        },
        'playlist_count': 18,
    }, {
        # single video embedded with data-playable containing vpid
        'url': 'http://www.bbc.com/news/world-europe-32041533',
        'info_dict': {
            'id': 'p02mprgb',
            'ext': 'mp4',
            'title': 'Aerial footage showed the site of the crash in the Alps - courtesy BFM TV',
            'description': 'md5:2868290467291b37feda7863f7a83f54',
            'duration': 47,
            'timestamp': 1427219242,
            'upload_date': '20150324',
        },
        'params': {
            # rtmp download
            'skip_download': True,
        }
    }, {
        # article with single video embedded with data-playable containing XML playlist
        # with direct video links as progressiveDownloadUrl (for now these are extracted)
        # and playlist with f4m and m3u8 as streamingUrl
        'url': 'http://www.bbc.com/turkce/haberler/2015/06/150615_telabyad_kentin_cogu',
        'info_dict': {
            'id': '150615_telabyad_kentin_cogu',
            'ext': 'mp4',
            'title': "YPG: Tel Abyad'ın tamamı kontrolümüzde",
            'description': 'md5:33a4805a855c9baf7115fcbde57e7025',
            'timestamp': 1434397334,
            'upload_date': '20150615',
        },
        'params': {
            'skip_download': True,
        }
    }, {
        # single video embedded with data-playable containing XML playlists (regional section)
        'url': 'http://www.bbc.com/mundo/video_fotos/2015/06/150619_video_honduras_militares_hospitales_corrupcion_aw',
        'info_dict': {
            'id': '150619_video_honduras_militares_hospitales_corrupcion_aw',
            'ext': 'mp4',
            'title': 'Honduras militariza sus hospitales por nuevo escándalo de corrupción',
            'description': 'md5:1525f17448c4ee262b64b8f0c9ce66c8',
            'timestamp': 1434713142,
            'upload_date': '20150619',
        },
        'params': {
            'skip_download': True,
        }
    }, {
        # single video from video playlist embedded with vxp-playlist-data JSON
        'url': 'http://www.bbc.com/news/video_and_audio/must_see/33376376',
        'info_dict': {
            'id': 'p02w6qjc',
            'ext': 'mp4',
            'title': '''Judge Mindy Glazer: "I'm sorry to see you here... I always wondered what happened to you"''',
            'duration': 56,
            'description': '''Judge Mindy Glazer: "I'm sorry to see you here... I always wondered what happened to you"''',
        },
        'params': {
            'skip_download': True,
        }
    }, {
        # single video story with digitalData
        'url': 'http://www.bbc.com/travel/story/20150625-sri-lankas-spicy-secret',
        'info_dict': {
            'id': 'p02q6gc4',
            'ext': 'flv',
            'title': 'Sri Lanka's spicy secret',
            'description': 'As a new train line to Jaffna opens up the country's north, travellers can experience a truly distinct slice of Tamil culture.',
            'timestamp': 1437674293,
            'upload_date': '20150723',
        },
        'params': {
            # rtmp download
            'skip_download': True,
        }
    }, {
        # single video story without digitalData
        'url': 'http://www.bbc.com/autos/story/20130513-hyundais-rock-star',
        'info_dict': {
            'id': 'p018zqqg',
            'ext': 'mp4',
            'title': 'Hyundai Santa Fe Sport: Rock star',
            'description': 'md5:b042a26142c4154a6e472933cf20793d',
            'timestamp': 1415867444,
            'upload_date': '20141113',
        },
        'params': {
            # rtmp download
            'skip_download': True,
        }
    }, {
        # single video embedded with Morph
        'url': 'http://www.bbc.co.uk/sport/live/olympics/36895975',
        'info_dict': {
            'id': 'p041vhd0',
            'ext': 'mp4',
            'title': "Nigeria v Japan - Men's First Round",
            'description': 'Live coverage of the first round from Group B at the Amazonia Arena.',
            'duration': 7980,
            'uploader': 'BBC Sport',
            'uploader_id': 'bbc_sport',
        },
        'params': {
            # m3u8 download
            'skip_download': True,
        },
        'skip': 'Georestricted to UK',
    }, {
        # single video with playlist.sxml URL in playlist param
        'url': 'http://www.bbc.com/sport/0/football/33653409',
        'info_dict': {
            'id': 'p02xycnp',
            'ext': 'mp4',
            'title': 'Transfers: Cristiano Ronaldo to Man Utd, Arsenal to spend?',
            'description': 'BBC Sport\'s David Ornstein has the latest transfer gossip, including rumours of a Manchester United return for Cristiano Ronaldo.',
            'duration': 140,
        },
        'params': {
            # rtmp download
            'skip_download': True,
        }
    }, {
        # article with multiple videos embedded with playlist.sxml in playlist param
        'url': 'http://www.bbc.com/sport/0/football/34475836',
        'info_dict': {
            'id': '34475836',
            'title': 'Jurgen Klopp: Furious football from a witty and winning coach',
            'description': 'Fast-paced football, wit, wisdom and a ready smile - why Liverpool fans should come to love new boss Jurgen Klopp.',
        },
        'playlist_count': 3,
    }, {
        # school report article with single video
        'url': 'http://www.bbc.co.uk/schoolreport/35744779',
        'info_dict': {
            'id': '35744779',
            'title': 'School which breaks down barriers in Jerusalem',
        },
        'playlist_count': 1,
    }, {
        # single video with playlist URL from weather section
        'url': 'http://www.bbc.com/weather/features/33601775',
        'only_matching': True,
    }, {
        # custom redirection to www.bbc.com
        'url': 'http://www.bbc.co.uk/news/science-environment-33661876',
        'only_matching': True,
    }, {
        # single video article embedded with data-media-vpid
        'url': 'http://www.bbc.co.uk/sport/rowing/35908187',
        'only_matching': True,
    }]

    @classmethod
    def suitable(cls, url):
        EXCLUDE_IE = (BBCCoUkIE, BBCCoUkArticleIE, BBCCoUkIPlayerPlaylistIE, BBCCoUkPlaylistIE)
        return (False if any(ie.suitable(url) for ie in EXCLUDE_IE)
                else super(BBCIE, cls).suitable(url))

    def _extract_from_media_meta(self, media_meta, video_id):
        # Direct links to media in media metadata (e.g.
        # http://www.bbc.com/turkce/haberler/2015/06/150615_telabyad_kentin_cogu)
        # TODO: there are also f4m and m3u8 streams incorporated in playlist.sxml
        source_files = media_meta.get('sourceFiles')
        if source_files:
            return [{
                'url': f['url'],
                'format_id': format_id,
                'ext': f.get('encoding'),
                'tbr': float_or_none(f.get('bitrate'), 1000),
                'filesize': int_or_none(f.get('filesize')),
            } for format_id, f in source_files.items() if f.get('url')], []

        programme_id = media_meta.get('externalId')
        if programme_id:
            return self._download_media_selector(programme_id)

        # Process playlist.sxml as legacy playlist
        href = media_meta.get('href')
        if href:
            playlist = self._download_legacy_playlist_url(href)
            _, _, _, _, formats, subtitles = self._extract_from_legacy_playlist(playlist, video_id)
            return formats, subtitles

        return [], []

    def _extract_from_playlist_sxml(self, url, playlist_id, timestamp):
        programme_id, title, description, duration, formats, subtitles = \
            self._process_legacy_playlist_url(url, playlist_id)
        self._sort_formats(formats)
        return {
            'id': programme_id,
            'title': title,
            'description': description,
            'duration': duration,
            'timestamp': timestamp,
            'formats': formats,
            'subtitles': subtitles,
        }

    def _real_extract(self, url):
        playlist_id = self._match_id(url)

        webpage = self._download_webpage(url, playlist_id)

        json_ld_info = self._search_json_ld(webpage, playlist_id, default={})
        timestamp = json_ld_info.get('timestamp')

        playlist_title = json_ld_info.get('title')
        if not playlist_title:
            playlist_title = self._og_search_title(
                webpage, default=None) or self._html_search_regex(
                r'<title>(.+?)</title>', webpage, 'playlist title', default=None)
            if playlist_title:
                playlist_title = re.sub(r'(.+)\s*-\s*BBC.*?$', r'\1', playlist_title).strip()

        playlist_description = json_ld_info.get(
            'description') or self._og_search_description(webpage, default=None)

        if not timestamp:
            timestamp = parse_iso8601(self._search_regex(
                [r'<meta[^>]+property="article:published_time"[^>]+content="([^"]+)"',
                 r'itemprop="datePublished"[^>]+datetime="([^"]+)"',
                 r'"datePublished":\s*"([^"]+)'],
                webpage, 'date', default=None))

        entries = []

        # article with multiple videos embedded with playlist.sxml (e.g.
        # http://www.bbc.com/sport/0/football/34475836)
        playlists = re.findall(r'<param[^>]+name="playlist"[^>]+value="([^"]+)"', webpage)
        playlists.extend(re.findall(r'data-media-id="([^"]+/playlist\.sxml)"', webpage))
        if playlists:
            entries = [
                self._extract_from_playlist_sxml(playlist_url, playlist_id, timestamp)
                for playlist_url in playlists]

        # news article with multiple videos embedded with data-playable
        data_playables = re.findall(r'data-playable=(["\'])({.+?})\1', webpage)
        if data_playables:
            for _, data_playable_json in data_playables:
                data_playable = self._parse_json(
                    unescapeHTML(data_playable_json), playlist_id, fatal=False)
                if not data_playable:
                    continue
                settings = data_playable.get('settings', {})
                if settings:
                    # data-playable with video vpid in settings.playlistObject.items (e.g.
                    # http://www.bbc.com/news/world-us-canada-34473351)
                    playlist_object = settings.get('playlistObject', {})
                    if playlist_object:
                        items = playlist_object.get('items')
                        if items and isinstance(items, list):
                            title = playlist_object['title']
                            description = playlist_object.get('summary')
                            duration = int_or_none(items[0].get('duration'))
                            programme_id = items[0].get('vpid')
                            formats, subtitles = self._download_media_selector(programme_id)
                            self._sort_formats(formats)
                            entries.append({
                                'id': programme_id,
                                'title': title,
                                'description': description,
                                'timestamp': timestamp,
                                'duration': duration,
                                'formats': formats,
                                'subtitles': subtitles,
                            })
                    else:
                        # data-playable without vpid but with a playlist.sxml URLs
                        # in otherSettings.playlist (e.g.
                        # http://www.bbc.com/turkce/multimedya/2015/10/151010_vid_ankara_patlama_ani)
                        playlist = data_playable.get('otherSettings', {}).get('playlist', {})
                        if playlist:
                            entry = None
                            for key in ('streaming', 'progressiveDownload'):
                                playlist_url = playlist.get('%sUrl' % key)
                                if not playlist_url:
                                    continue
                                try:
                                    info = self._extract_from_playlist_sxml(
                                        playlist_url, playlist_id, timestamp)
                                    if not entry:
                                        entry = info
                                    else:
                                        entry['title'] = info['title']
                                        entry['formats'].extend(info['formats'])
                                except Exception as e:
                                    # Some playlist URL may fail with 500, at the same time
                                    # the other one may work fine (e.g.
                                    # http://www.bbc.com/turkce/haberler/2015/06/150615_telabyad_kentin_cogu)
                                    if isinstance(e.cause, compat_HTTPError) and e.cause.code == 500:
                                        continue
                                    raise
                            if entry:
                                self._sort_formats(entry['formats'])
                                entries.append(entry)

        if entries:
            return self.playlist_result(entries, playlist_id, playlist_title, playlist_description)

        # single video story (e.g. http://www.bbc.com/travel/story/20150625-sri-lankas-spicy-secret)
        programme_id = self._search_regex(
            [r'data-(?:video-player|media)-vpid="(%s)"' % self._ID_REGEX,
             r'<param[^>]+name="externalIdentifier"[^>]+value="(%s)"' % self._ID_REGEX,
             r'videoId\s*:\s*["\'](%s)["\']' % self._ID_REGEX],
            webpage, 'vpid', default=None)

        if programme_id:
            formats, subtitles = self._download_media_selector(programme_id)
            self._sort_formats(formats)
            # digitalData may be missing (e.g. http://www.bbc.com/autos/story/20130513-hyundais-rock-star)
            digital_data = self._parse_json(
                self._search_regex(
                    r'var\s+digitalData\s*=\s*({.+?});?\n', webpage, 'digital data', default='{}'),
                programme_id, fatal=False)
            page_info = digital_data.get('page', {}).get('pageInfo', {})
            title = page_info.get('pageName') or self._og_search_title(webpage)
            description = page_info.get('description') or self._og_search_description(webpage)
            timestamp = parse_iso8601(page_info.get('publicationDate')) or timestamp
            return {
                'id': programme_id,
                'title': title,
                'description': description,
                'timestamp': timestamp,
                'formats': formats,
                'subtitles': subtitles,
            }

        # Morph based embed (e.g. http://www.bbc.co.uk/sport/live/olympics/36895975)
        # There are several setPayload calls may be present but the video
        # seems to be always related to the first one
        morph_payload = self._parse_json(
            self._search_regex(
                r'Morph\.setPayload\([^,]+,\s*({.+?})\);',
                webpage, 'morph payload', default='{}'),
            playlist_id, fatal=False)
        if morph_payload:
            components = try_get(morph_payload, lambda x: x['body']['components'], list) or []
            for component in components:
                if not isinstance(component, dict):
                    continue
                lead_media = try_get(component, lambda x: x['props']['leadMedia'], dict)
                if not lead_media:
                    continue
                identifiers = lead_media.get('identifiers')
                if not identifiers or not isinstance(identifiers, dict):
                    continue
                programme_id = identifiers.get('vpid') or identifiers.get('playablePid')
                if not programme_id:
                    continue
                title = lead_media.get('title') or self._og_search_title(webpage)
                formats, subtitles = self._download_media_selector(programme_id)
                self._sort_formats(formats)
                description = lead_media.get('summary')
                uploader = lead_media.get('masterBrand')
                uploader_id = lead_media.get('mid')
                duration = None
                duration_d = lead_media.get('duration')
                if isinstance(duration_d, dict):
                    duration = parse_duration(dict_get(
                        duration_d, ('rawDuration', 'formattedDuration', 'spokenDuration')))
                return {
                    'id': programme_id,
                    'title': title,
                    'description': description,
                    'duration': duration,
                    'uploader': uploader,
                    'uploader_id': uploader_id,
                    'formats': formats,
                    'subtitles': subtitles,
                }

        def extract_all(pattern):
            return list(filter(None, map(
                lambda s: self._parse_json(s, playlist_id, fatal=False),
                re.findall(pattern, webpage))))

        # Multiple video article (e.g.
        # http://www.bbc.co.uk/blogs/adamcurtis/entries/3662a707-0af9-3149-963f-47bea720b460)
        EMBED_URL = r'https?://(?:www\.)?bbc\.co\.uk/(?:[^/]+/)+%s(?:\b[^"]+)?' % self._ID_REGEX
        entries = []
        for match in extract_all(r'new\s+SMP\(({.+?})\)'):
            embed_url = match.get('playerSettings', {}).get('externalEmbedUrl')
            if embed_url and re.match(EMBED_URL, embed_url):
                entries.append(embed_url)
        entries.extend(re.findall(
            r'setPlaylist\("(%s)"\)' % EMBED_URL, webpage))
        if entries:
            return self.playlist_result(
                [self.url_result(entry_, 'BBCCoUk') for entry_ in entries],
                playlist_id, playlist_title, playlist_description)

        # Multiple video article (e.g. http://www.bbc.com/news/world-europe-32668511)
        medias = extract_all(r"data-media-meta='({[^']+})'")

        if not medias:
            # Single video article (e.g. http://www.bbc.com/news/video_and_audio/international)
            media_asset = self._search_regex(
                r'mediaAssetPage\.init\(\s*({.+?}), "/',
                webpage, 'media asset', default=None)
            if media_asset:
                media_asset_page = self._parse_json(media_asset, playlist_id, fatal=False)
                medias = []
                for video in media_asset_page.get('videos', {}).values():
                    medias.extend(video.values())

        if not medias:
            # Multiple video playlist with single `now playing` entry (e.g.
            # http://www.bbc.com/news/video_and_audio/must_see/33767813)
            vxp_playlist = self._parse_json(
                self._search_regex(
                    r'<script[^>]+class="vxp-playlist-data"[^>]+type="application/json"[^>]*>([^<]+)</script>',
                    webpage, 'playlist data'),
                playlist_id)
            playlist_medias = []
            for item in vxp_playlist:
                media = item.get('media')
                if not media:
                    continue
                playlist_medias.append(media)
                # Download single video if found media with asset id matching the video id from URL
                if item.get('advert', {}).get('assetId') == playlist_id:
                    medias = [media]
                    break
            # Fallback to the whole playlist
            if not medias:
                medias = playlist_medias

        entries = []
        for num, media_meta in enumerate(medias, start=1):
            formats, subtitles = self._extract_from_media_meta(media_meta, playlist_id)
            if not formats:
                continue
            self._sort_formats(formats)

            video_id = media_meta.get('externalId')
            if not video_id:
                video_id = playlist_id if len(medias) == 1 else '%s-%s' % (playlist_id, num)

            title = media_meta.get('caption')
            if not title:
                title = playlist_title if len(medias) == 1 else '%s - Video %s' % (playlist_title, num)

            duration = int_or_none(media_meta.get('durationInSeconds')) or parse_duration(media_meta.get('duration'))

            images = []
            for image in media_meta.get('images', {}).values():
                images.extend(image.values())
            if 'image' in media_meta:
                images.append(media_meta['image'])

            thumbnails = [{
                'url': image.get('href'),
                'width': int_or_none(image.get('width')),
                'height': int_or_none(image.get('height')),
            } for image in images]

            entries.append({
                'id': video_id,
                'title': title,
                'thumbnails': thumbnails,
                'duration': duration,
                'timestamp': timestamp,
                'formats': formats,
                'subtitles': subtitles,
            })

        return self.playlist_result(entries, playlist_id, playlist_title, playlist_description)

class BBCCoUkArticleIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?bbc\.co\.uk/programmes/articles/(?P<id>[a-zA-Z0-9]+)'
    IE_NAME = 'bbc.co.uk:article'
    IE_DESC = 'BBC articles'

    _TEST = {
        'url': 'http://www.bbc.co.uk/programmes/articles/3jNQLTMrPlYGTBn0WV6M2MS/not-your-typical-role-model-ada-lovelace-the-19th-century-programmer',
        'info_dict': {
            'id': '3jNQLTMrPlYGTBn0WV6M2MS',
            'title': 'Calculating Ada: The Countess of Computing - Not your typical role model: Ada Lovelace the 19th century programmer - BBC Four',
            'description': 'Hannah Fry reveals some of her surprising discoveries about Ada Lovelace during filming.',
        },
        'playlist_count': 4,
        'add_ie': ['BBCCoUk'],
    }

    def _real_extract(self, url):
        playlist_id = self._match_id(url)

        webpage = self._download_webpage(url, playlist_id)

        title = self._og_search_title(webpage)
        description = self._og_search_description(webpage).strip()

        entries = [self.url_result(programme_url) for programme_url in re.findall(
            r'<div[^>]+typeof="Clip"[^>]+resource="([^"]+)"', webpage)]

        return self.playlist_result(entries, playlist_id, title, description)

class BBCCoUkPlaylistBaseIE(InfoExtractor):
    def _entries(self, webpage, url, playlist_id):
        single_page = 'page' in compat_urlparse.parse_qs(
            compat_urlparse.urlparse(url).query)
        for page_num in itertools.count(2):
            for video_id in re.findall(
                    self._VIDEO_ID_TEMPLATE % BBCCoUkIE._ID_REGEX, webpage):
                yield self.url_result(
                    self._URL_TEMPLATE % video_id, BBCCoUkIE.ie_key())
            if single_page:
                return
            next_page = self._search_regex(
                r'<li[^>]+class=(["\'])pagination_+next\1[^>]*><a[^>]+href=(["\'])(?P<url>(?:(?!\2).)+)\2',
                webpage, 'next page url', default=None, group='url')
            if not next_page:
                break
            webpage = self._download_webpage(
                compat_urlparse.urljoin(url, next_page), playlist_id,
                'Downloading page %d' % page_num, page_num)

    def _real_extract(self, url):
        playlist_id = self._match_id(url)

        webpage = self._download_webpage(url, playlist_id)

        title, description = self._extract_title_and_description(webpage)

        return self.playlist_result(
            self._entries(webpage, url, playlist_id),
            playlist_id, title, description)

class BBCCoUkIPlayerPlaylistIE(BBCCoUkPlaylistBaseIE):
    IE_NAME = 'bbc.co.uk:iplayer:playlist'
    _VALID_URL = r'https?://(?:www\.)?bbc\.co\.uk/iplayer/(?:episodes|group)/(?P<id>%s)' % BBCCoUkIE._ID_REGEX
    _URL_TEMPLATE = 'http://www.bbc.co.uk/iplayer/episode/%s'
    _VIDEO_ID_TEMPLATE = r'data-ip-id=["\'](%s)'
    _TESTS = [{
        'url': 'http://www.bbc.co.uk/iplayer/episodes/b05rcz9v',
        'info_dict': {
            'id': 'b05rcz9v',
            'title': 'The Disappearance',
            'description': 'French thriller serial about a missing teenager.',
        },
        'playlist_mincount': 6,
        'skip': 'This programme is not currently available on BBC iPlayer',
    }, {
        # Available for over a year unlike 30 days for most other programmes
        'url': 'http://www.bbc.co.uk/iplayer/group/p02tcc32',
        'info_dict': {
            'id': 'p02tcc32',
            'title': 'Bohemian Icons',
            'description': 'md5:683e901041b2fe9ba596f2ab04c4dbe7',
        },
        'playlist_mincount': 10,
    }]

    def _extract_title_and_description(self, webpage):
        title = self._search_regex(r'<h1>([^<]+)</h1>', webpage, 'title', fatal=False)
        description = self._search_regex(
            r'<p[^>]+class=(["\'])subtitle\1[^>]*>(?P<value>[^<]+)</p>',
            webpage, 'description', fatal=False, group='value')
        return title, description

class BBCCoUkPlaylistIE(BBCCoUkPlaylistBaseIE):
    IE_NAME = 'bbc.co.uk:playlist'
    _VALID_URL = r'https?://(?:www\.)?bbc\.co\.uk/programmes/(?P<id>%s)/(?:episodes|broadcasts|clips)' % BBCCoUkIE._ID_REGEX
    _URL_TEMPLATE = 'http://www.bbc.co.uk/programmes/%s'
    _VIDEO_ID_TEMPLATE = r'data-pid=["\'](%s)'
    _TESTS = [{
        'url': 'http://www.bbc.co.uk/programmes/b05rcz9v/clips',
        'info_dict': {
            'id': 'b05rcz9v',
            'title': 'The Disappearance - Clips - BBC Four',
            'description': 'French thriller serial about a missing teenager.',
        },
        'playlist_mincount': 7,
    }, {
        # multipage playlist, explicit page
        'url': 'http://www.bbc.co.uk/programmes/b00mfl7n/clips?page=1',
        'info_dict': {
            'id': 'b00mfl7n',
            'title': 'Frozen Planet - Clips - BBC One',
            'description': 'md5:65dcbf591ae628dafe32aa6c4a4a0d8c',
        },
        'playlist_mincount': 24,
    }, {
        # multipage playlist, all pages
        'url': 'http://www.bbc.co.uk/programmes/b00mfl7n/clips',
        'info_dict': {
            'id': 'b00mfl7n',
            'title': 'Frozen Planet - Clips - BBC One',
            'description': 'md5:65dcbf591ae628dafe32aa6c4a4a0d8c',
        },
        'playlist_mincount': 142,
    }, {
        'url': 'http://www.bbc.co.uk/programmes/b05rcz9v/broadcasts/2016/06',
        'only_matching': True,
    }, {
        'url': 'http://www.bbc.co.uk/programmes/b05rcz9v/clips',
        'only_matching': True,
    }, {
        'url': 'http://www.bbc.co.uk/programmes/b055jkys/episodes/player',
        'only_matching': True,
    }]

    def _extract_title_and_description(self, webpage):
        title = self._og_search_title(webpage, fatal=False)
        description = self._og_search_description(webpage)
        return title, description

redpajama_set_name: RedPajamaGithub


No matter where you live, it always feels good to go home.
With this set of 4 wooden coasters you can be sure to add a little bit of fancy under that refreshing drink. And maybe even spruce up your table and home.
The hand drawn houses have been etched on the surface of the wood and someone has gone and cut out all if the windows. The coasters have been laser cut from Colour Rimu wood, that has been hand rubbed with tung oil to protect them.
Size: 3.5" x 3.5" and approx .25" thick.
Super cute silhouetted houses sure do make for some super fancy drink coasters!
Perfect for a new couple, or a great housewarming gift!
Love this pin! Thank you!


Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Emma Viola Engram was born in 1852 in Barbour County, Alabama. She was the daughter of Oliver Kanady Engram and Mariah Louise Dennard. Emma Viola Engram died on 11 October 1884 in Barbour County, Alabama.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Henry I. Engram was born on 10 June 1820 in Lenoir, North Carolina. He was the son of Edward Engram and Elizabeth Kanady. Henry I. Engram married Harrett Clay on 20 September 1838. Henry I. Engram died on 6 September 1878 in Clairborne Parish, Louisiana, at age 58.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Harrett Clay married Henry I. Engram, son of Edward Engram and Elizabeth Kanady, on 20 September 1838. As of 20 September 1838,her married name was Engram.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell Buried at family cemetery near Fort Gaines, GA. Seaborn Taylor Engram was born on 7 May 1824. He was the son of Edward Engram and Elizabeth Kanady. Seaborn Taylor Engram married Elizabeth Grace on 3 October 1845 at Houston County, Georgia. Seaborn Taylor Engram married Sarah A. Stewart on 3 May 1853. Seaborn Taylor Engram married Elizabeth G. Waits circa 1879. Seaborn Taylor Engram died on 19 November 1908 in Near Fort Gaines, Georgia, at age 84.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell On page #5 her name becomes Elizabeth Gray Engram - why? Elizabeth Grace married Seaborn Taylor Engram, son of Edward Engram and Elizabeth Kanady, on 3 October 1845 at Houston County, Georgia. As of 3 October 1845,her married name was Engram.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. John Irby Engram was born on 8 April 1847. He was the son of Seaborn Taylor Engram and Elizabeth Grace.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Celia Engram was born on 25 December 1848. She was the daughter of Seaborn Taylor Engram and Elizabeth Grace.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell Second daughter of Seaborn/Elizabeth Grace Engram Died in infancy. Elizabeth Engram was born in 1850. She was the daughter of Seaborn Taylor Engram and Elizabeth Grace.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Sarah A. Stewart married Seaborn Taylor Engram, son of Edward Engram and Elizabeth Kanady, on 3 May 1853. As of 3 May 1853,her married name was Engram.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell Page 6 says he had three children with second marraige but four are listed. William Henry Engram was born on 26 February 1854. He was the son of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell Second son of Seaborn/Sarah Engram. Madison K. Engram was born on 30 December 1855. He was the son of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell Had several children. Ella Virginia Engram was born in February 1856. She was the daughter of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Lamantha C. Engram was born on 18 December 1860. She was the daughter of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell Had no children. Arabella Lee Engram was born on 31 December 1862. She was the daughter of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Amanda Engram was born on 10 January 1864. She was the daughter of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Malcolm Cicero Engram was born on 10 November 1866. He was the son of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Edward Taylor Engram was born on 29 July 1869. He was the son of Seaborn Taylor Engram and Sarah A. Stewart. Edward Taylor Engram died in 1941. He was buried at Oakland Cemetery, Bay County, Florida.
Source:Paper from Captian Robert C. Engram to Majorie Bagwell. Newton Harvey Engram was born on 7 August 1871. He was the son of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Claudia A. Engram was born on 16 November 1873. She was the daughter of Seaborn Taylor Engram and Sarah A. Stewart.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Elizabeth G. Waits married Seaborn Taylor Engram, son of Edward Engram and Elizabeth Kanady, circa 1879. As of circa 1879,her married name was Engram.
William Franklin Engram was born on 14 July 1827 in Houston County, Georgia. He was the son of Edward Engram and Elizabeth Kanady. William Franklin Engram married Nancy Johnson, daughter of Richard Johnson and Jane Johnson, on 31 December 1845.2 Joined the Confederate Army and was promoted to Captain of an artillery company and served until the end of the Civil War.2 William Franklin Engram married Ann Marshall on 12 May 1880 at Houston County, Georgia. William Franklin Engram died on 8 December 1891 in Houston County, Georgia, at age 64. He died on 8 December 1891 in Near Perry, Houston County, Georgia, at age 64.
[S91] Letter, Captian Robert C. Engram to Majorie (Goff) Bagwell.
[S80] Frank C. Folks, "Georgia and Florida / Souvenir Sketches."
Source:Paper from Captain Robert C. Engram to Majorie Bagwell She was from the same place, Houston County Georgia, as William Engram her husband. Nancy Johnson was born in 1829. She was the daughter of Richard Johnson and Jane Johnson. Nancy Johnson married William Franklin Engram, son of Edward Engram and Elizabeth Kanady, on 31 December 1845.1 As of 31 December 1845,her married name was Engram. Nancy Johnson died in 1871.
William Henry Engram was also known as Henry Engram. He was born circa 1846 in Georgia. He was the son of William Franklin Engram and Nancy Johnson.
Robert Oliver Engram was born on 7 July 1850 in Perry, Houston County, Georgia. He was the son of William Franklin Engram and Nancy Johnson. Robert O. Engram, M.D., was born in Houston County, Ga, January 7, 1849. His father, William F. Engram, was born in Georgia, and was a son of Edward Engram, who emigrated from France to America in the latter part of the eighteenth century, came to Pennsylvania and afterwards to Georgia, and died in Houston County. William F. was the seventh child of eight children born to him and his wife, Jane Maxey. William F. followed farming all his life, and has been for many years one of the most substantial men in Houston County. In 1862 he joined the Confederate army, and was soon afterward promoted to captain of an artillery company, and served until the close of the war. He now resides in Houston County. His wife, Nancy A. Johnson, was born in Houston County. She bore him five children, viz: William H., Robert O., Tabitha J., Virginia C. and George F. Mrs. Engram was a daughter of Richard and Jane (Johnson) Johnson. The subject of this sketch was brought up on the farm in Houston County, and educated in early life in the common schools. In 1864 he joined the Confederate army with Morgan, and served until the close of the war. He then entered the University of Virginia and graduated from that institution in 1868. He soon took up the study of medicine and graduated from the Jefferson Medical College, of Philadelphia, in 1872. He was then appointed resident physician in the Pennsylvania Hospital at Philadelphia, and served in that capacity for a little more than a year, when he went to the charity hospital, of that city, and remained there until the fall of 1873, when he returned to Georgia and practiced his profession in Houston County until 1874, at which time he removed to Montezuma, where he has since given his attention to the practice of medicine, and is one of the leading practitioners in southwest Georgia. He is a member of the American Medical Association, the Georgia Medical Association and the Southwest Georgia Medical Association, also the Academy of Natural Science of Philadelphia. January 15, 1881, he was married to Ella V. Horne, daughter of Thomas W. M. Horne, of Americus, Ga. Three children have been born to this union, viz: Lionel B., Robert E. and William H. Dr. Engram is a F. and A. M., in politics is a Democrat, and has served eight terms in the city council of Montezuma and three terms as mayor of his city.2 Robert Oliver Engram began military service in 1864 for Confederate Army (CSA) with [General John Hunt] Morgan.2 He graduated in 1868 from the University of Virginia, Charlottesville, Virginia.2 He graduated in 1872 from Jefferson Medical College at Philadelphia, Pennsylvania.2 He lived in 1874 in Montezuma, Georgia.2 He married Ella V. Horne, daughter of Thomas W. M. Horne, on 15 January 1881.2 Robert Oliver Engram died on 10 June 1893 in Montezuma, Macon County, Georgia, at age 42. He was buried at Felton Cemetery, Montezuma, Macon County, Georgia.
George Franklin Engram was born in 1864 in Houston County, Georgia. He was the son of William Franklin Engram and Nancy Johnson. George Franklin Engram died in 1882.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Mattie Engram was born on 7 September 1851 in Perry, Houston County, Georgia. She was the daughter of William Franklin Engram and Nancy Johnson.
Source:Paper from Captain Robert C. Engram to Majorie Bagwell. Virginia Campbelle Engram was born in 1854. She was the daughter of William Franklin Engram and Nancy Johnson. Virginia Campbelle Engram died on 18 January 1879 in Drayton, Dooly County, Georgia.
Ann Marshall married William Franklin Engram, son of Edward Engram and Elizabeth Kanady, on 12 May 1880 at Houston County, Georgia.
Published in The Calhoun Times, Calhoun, Georgia, on July 4, 1889.Mr. Engram was born in Houston County, Ga., Sept. 16th, 1830, and at the time of his death was in his fifty-ninth year. He moved to this county about twenty years ago, bringing his wife and several children, and located on a farm, to which he devoted the greater part of his time until 1880 when he was elected clerk of the superior court, which office he held for six years, having been elected for three successive terms.He was a consistent member of the Baptist church for twenty-four years, and led a moral and christian life, at all times taking great interest in the progress of the church. He was the father of eleven children, six of whom preceded him to the great beyond. He was a kind and affectionate husband and father, and the hearts of our people go out to his afflicted family.The funeral services were conducted at his late residence on Sunday evening by Rev. A.S. Tatum and his remains laid to rest at the Chandler cemetery with Masonic ceremony. He was buried at Chandler Cemetery, Gordon County, Georgia.
Quintine T. Johnson was born circa 1836 in Georgia. She married Edward W. Engram, son of Edward Engram and Elizabeth Kanady, on 15 October 1851. As of 15 October 1851,her married name was Engram.


text:
BrandNew Music taking a different outlook on success
In an interview held in 2012, BrandNew Music's CEO Rhymer stated that within three years, he would make his company into one of the largest five companies in Korea. The reported who interviewed him laughed it off seemingly as if it was a joke. Fast forward to the present and BrandNew Music profits have doubled since 2013, and with a year left before the promised date, it seems like Rhymer may actually reach his goal.
The hip hop movement in South Korea has been growing steadily for the past 2 years and Rhymer stated, "I think it's just the beginning, people are calling hip hop the new trend but I think it's just that the public is starting to notice hip hop."
BrandNew Music artists include Verbal Jint, Bumkey, As One, Phantom, and Troy, as well as San-E who experienced massive success with his "A Midsummer Night's Sweetness" with Raina.
A reporter recently caught up with the busy CEO Rhymer and had the chance to ask him again about his chances of becoming on the of top five companies in Korea, to which Rhymer responded, "I've changed thoughts and I have no greed in that aspect any more. I just want to do what I can and make a company that does what it does best."
When asked "Why the change of heart?" Rhymer said, "There's still a lot to learn. Right now I'm focusing on expanding the field of business within hip hop. Right now it's music, albums, and events. We are looking into marketing aspects that will help us establish a more solid fan base and possibly expand our influence overseas. We are planning more collaborations with foreign artists. There's a world tour planned right now. 5 cities in North America, 2 in South America and 3 in Southeast Asia." At the moment, BrandNew Music is preparing for their BrandNew Year concert to be held on December 7th at the Olympic Hall.
Rhymer stated that he wants to break into overseas markets and also collaborate with different idols, "It's because people pay a lot of attention to Korean charts. Mnet Show Me the Money helped a lot as well. There will also be collaborations with idols as well. The feedback about the music is very positive as well. It's not just that they think it's cool that an Asian is rapping they are starting to respect our music."
Since hip hop music is still consider new in Korea, Rhymer stated he believes smooth hip hop was the key to getting the general public to start accepting hip hop. Rhymer plans to take BrandNew Music in a whole new different route, " I think it's more important to see how many different age groups we can reach out to and how we can improve the environment for hip hop artists. I want BrandNew Music to be the hub of hip hop. Not just make and sell music but be the channel for other artists or companies. I want to be the nicest and kindest company within hip hop."

redpajama_set_name: RedPajamaCommonCrawl


text:
Joe Downard's 'Seven Japanese Tales'
Monday 2 August 2021, 7:30pm
BOOK NOW – Evening Concert at The Yard
BOOK NOW – Live Stream from The Yard
Featuring: Joe Downard – Bass / James Copus – Trumpet / Alex Hitchcock – Saxophone / Rupert Cox – Synth / Will Barry – Piano / Felix Ambach – Drums
'Anyone who doubts there's a UK jazz scene worth taking note of should listen to Joe Downard's album. A truly impressive debut' — Jasper Høiby
One of the most in–demand bassists in the UK, Joe Downard is widely recognised for his skills as a performer and improvisor.
Joe is a crucial component to many of the UK's top rhythm sections that range from modern contemporary Jazz and Soul to Electronic and Western African music.
In 2020 Joe released his debut album, Seven Japanese Tales, featuring original compositions of his and a roster of the finest jazz musicians in Europe.
For their Manchester debut, Downard will play alongside Alex Hitchcock (tenor saxophone), James Copus (trumpet), Will Barry (piano), Rupert Cox (synths) and Felix Ambach (drums).
Joe Downard's website
In partnership with NQ Jazz and The Yard. Made possible by Arts Council England's Supporting Grassroots Live Music fund.
Please note: When attending in-person events please allow at least 30 minutes prior to the start time to be seated in a safe and socially distanced way ready for the performance.


This page was designed to help parents in their search for childcare parent resources. If finding child care was as easy as writing your requirements and ripping it up and throwing it in the fireplace we would all have our own Mary Poppins. The reality is agencies are great resources for parents and nannies. I know they can get a little pricey however please remember they are making it easier for you to find that perfect person, and they do a lot of work to ensure you get your own Mary Poppins.
Also keep in mind you are not the only one screening. Nannies want to be properly represented and usually want the parents checked out by an agency before they go into a new situation.
If you are not sure where to start of even what you are looking for, let them help you. The only thing you should know before you call is that you indeed want in-home child care. The agency will answer any questions you have and get you started.
Ask the agency if the registration fee includes the one year registration fee for temporary childcare (babysitting), this can come in handy both while you are looking for a permanent nanny and after if she/he is not available to help out one evening with overtime care, this can be a great benefit.


Planning ahead and preparing for inclement weather and natural disasters can help keep you and your family safe.
Cold weather puts extra strain on the heart. If you have heart disease or high blood pressure, follow your doctor's advice about performing strenuous work like shoveling the driveway in the cold. If you do have to work outside, be sure to dress in layers and work slowly.
Keep an eye on the sky. Look for darkening skies, flashes of light, or increasing wind.
Listen for the sound of thunder.
If you can hear thunder, you are close enough to be struck by lightning.
Go to safe shelter immediately. Listen to radio or television broadcasts for the latest weather forecasts.
Find shelter in a building or a car.
Know that telephone lines and metal pipes can conduct electricity.
Avoid using the telephone or other electronic appliances.
Avoid taking a bath or shower.
Turn off the air conditioner.
Draw blinds and shades over windows – if windows break due to objects blown by wind, the shades will prevent glass from shattering into your home.
If you are in the woods, take shelter under shorter trees.
If you are boating or swimming, return to land and seek shelter immediately.
Go to a low-lying, open place away from trees, metal poles, or other tall objects.
Make sure the place you pick is not subject to flooding.
Be a very small target – squat low to the ground, place your hands on your knees with your head between them. Do not lie flat on the ground – this will make you a larger target.
Tune into the radio or television for information and instructions.
Call 9-1-1 or local Emergency Medical Services (EMS) immediately.
The injured person may have received an electrical shock and may be burned, both where they were struck, and where the electricity left their body. Check both places for burns.
Give first aid. If breathing has stopped, begin rescue breathing. If the heart has stopped beating, a trained rescue person should give CPR.
Learn about your community's emergency plans, warning signals, evacuation routes, and locations of emergency shelters.
Plan and practice a flood evacuation route with your family.
Post emergency phone numbers at every phone.
Identify potential home hazards and know how to secure/protect them before the flood strikes.
Buy and install sump pumps with back up power.
Have a licensed electrician raise electric components at least 12" above your home's projected flood elevation level.
For drains, toilets and other sewer connections, install backflow valves to prevent floodwaters from entering.
Anchor fuel tanks which can contaminate your basement if torn free.
Gather emergency supplies and stay tuned to local radio or television stations for updates.
Turn off all utilities at the main power switch and close the main gas valve if evacuation appears necessary.
Fill bathtubs, sinks and plastic soda bottles for clean water.
Bring outdoor possessions, such as lawn furniture, grills and trashcans inside or tie them down securely.
Take only essential items with you.
If you have time, turn off the gas, electricity, and water.
Disconnect appliances to prevent electrical shock when power is restored.
Follow the designated evacuation routes and expect heavy traffic.
Do not attempt to drive or walk across creeks or flooded roads.
Monitor the radio or television for updates.
Prepare to evacuate to a shelter or to a neighbor's home if your home is damaged, or if you are instructed to do so by emergency personnel.
An emergency kit for your car with food, flares, booster cables, maps, tools, first aid kit, fire extinguisher, etc.


I got this from http://www.ukagriculture.com/uk_farming.cfm and it says that although there are 300,000 farms at an average of 140 acres / 57 hectares / .56sq km each the number is skewed by the size of farms in Scotland which average over 100 hectares / 247 acre / 1sq km so the actual average size is somewhere around 40 hectares / 98 acres / 0.4sq km. Whichever way you look at it the total active farming land in Britain is around 1.5m sq km. (.57km x 300000). This seems incredibly small when 75% of all surface area in this country is maintained by farmers. Having said that we exported £14bn worth of agriculture, but imported £32Bn.
Something's wrong somewhere, and if anything, I'm more confused than when I started!


To celebrate our 35th year of trading in Norwich, we've refurbished our factory showroom. It means that we can show the very best examples of the products we offer to both homeowners and trade customers.
And as part of the AstraFrame Trade Card benefits, builders, window installers and tradespeople can use the new showroom as their own.
The new orangery, constructed on the side of our factory showroom, was installed by our recommended local installers Patrick Holmes and Tony Zavanaiu. As it's an extension of our showroom, it gives homeowners an idea of how much light is let into the space and a real feel of how beautiful our bespoke orangery designs can look.
The orangery has Chartwell Green frames showing how great traditional frame colours can look against red brick. And you can see the high standard of workmanship of our recommended installers, too.
We've updated our window and door displays inside the factory showroom so that customers can see how the real products look and the quality of manufacturing. There are different style uPVC windows and doors as well as the best collection of composite doors in Norwich.
We celebrated our 35th anniversary year with an open day, where customers and suppliers joined our team to welcome the Lord Mayor of Norwich who officially opened our newly refurbished factory showroom.
It was great to show our guests around our factory on the day, to show how we manufacture everything in Norwich and use other local companies for our supplies. We buy our glass from Ecoglass (just 10 minutes down the road from our factory showroom) and our machinery is from Stuga, based in Great Yarmouth.
With an AstraFrame Trade Card, local tradespeople can reap all the benefits of our brand new factory showroom. You can use it as your own to show your customers the quality of products you install. We offer free marketing support and fast turnaround times too.
Apply for a trade card here or visit the new factory showroom at 50 Barker Street in Norwich.


On 28 June 1950, Congress officially recognized the importance of the Transportation Corps by making it a permanent branch of the Army. Transportation Corps support continued into the Korean War, the Vietnam Conflict, Grenada, Panama, Southwest Asia, Somali, Haiti and most recently in Bosnia.
The incorporation of the Transportation Corps into the U.S. Army's Regimental System on 31 July 1986, marked the beginning of a new era in the history of the Corps. Regimental affiliation fosters a spirit of pride, unity, cohesion, and cooperation among Transportation Corps soldiers and civilians and provides an organization that promotes and encourages professional development and growth. The activation of the Regiment marked the redesignation of several Transportation Corps training commands. The redesignation provided a link with renowned transportation units of the past. The Training Brigade was redesignated the 8th Transportation Brigade, honoring the 8th Transportation Group in Vietnam.
The United States Army Transportation Corps is one of the Army's youngest service branches, having been established in 1942. However, the origin of its vital role extends back as far as the Revolutionary War when animal-drawn transportation was used to move American and French forces. With the Civil War, came the extensive use of the Military Railway Service in moving the troops to battle. The importance of transportation for the military increased rapidly as the U.S. Army Transport Service appeared during the Spanish-American War; subsequently, the Transportation Service was created in World War II, the key role of transportation again became clear.
In March 1942, military transportation functions were taken from the Quartermaster Corps and given to the Transportation service of the newly created Services of Supply. On 31 July 1942, President Roosevelt, faced with the largest mobilization in history, established the Transportation Corps. This new Corps took over railway operations and maintenance from the Corps of Engineers in November 1942. From 1941 to 1945, the Transportation Corps moved 30 million soldiers within the United States and carried seven million soldiers and 126 million tons of supplies overseas, a decisive part in the Allied victory. From 1948 to 1949, the Transportation Corps again played a major role in the Berlin Airlift.
During World War II, the Transportation Corps conducted operations in the deserts of North Africa, the jungles of the Pacific theater, over the beaches of Normandy and throughout Europe. From its inception in 1942 through 1945, transporters moved 30 million soldiers in the United States and carried 7 million soldiers and 126 million tons of supplies overseas, playing a decisive part in the Allied victory.
The Berlin Airlift from 1948-49 kept the Allied portion of Berlin sustained until the Russians allowed supplies to recommence. The success of the airlift was due in large part to the dedication and skill of Transportation Corps soldiers. Transporters ensured smooth operations and cargo flow in Korea, Vietnam, Grenada, Panama and into Saudi Arabia. After the 82d Airborne Division, transporters from the 7th Transportation Group, FT Eustis, VA were the next soldiers to deploy to the Middle East, readying the ports, air terminals and lines of communication for the rest of the U.S. military. Transporters are among the first to deploy and the last to return from conflicts and exercises wherever they occur. Without the expertise and dedication of the 2400 officers and 20,900 enlisted soldiers of the Transportation Corps, operations of the Army would literally grind to a halt.
On 26 July 1986, the Transportation Corps formally instituted the Regimental system of organization during the annual TC worldwide conference at FT Eustis, VA. The Regimental Crest and motto, "Spearhead of Logistics" were also formally adopted at this time.
Currently, the Transportation Corps is the third-smallest branch in the Army. Of the 2428 officers on active duty, 20% are female, 80% male. Between 120-160 TC 2LTs are assessed each year. TC is a shortage branch into which Combat Arms 1LTs and CPTs transfer each year, as the demand for Transportation Corps officers increases with rank.
Transportation Corps lieutenants can be assigned to three different areas for their platoon leader experience. These areas are truck, boat, and terminal operations. Approximately 80% of Transportation Corps 2LTs are initially assigned as Truck Platoon Leaders. Locations range virtually across the globe -- from Korea to Hawaii, from Alaska to Fort Lewis, WA, from FT Devens, MA to Nurnberg, FRG, and hundreds of places in between.
Light truck companies and POL units usually support maneuver forces directly, hauling cargo and soldiers in support of exercises and deployments for a brigade, division, or corps. Vehicles include the 5 ton truck and tractor, and the 30 foot trailer and 5000 gallon tanker. The Platoon Leader will usually deploy with his/her platoon if the exercise/deployment is large or complex, and the LT will often serve as the OIC for the support element. In CONUS, expect to deploy to the National Training Center (NTC), Team Spirit (Korea) or to any other large-scale exercises with your supported combat unit.
Medium truck Platoon Leaders have a slightly different mission as the M915 tractor trailer combination is primarily an on-road asset. The M915 is a 14 ton tractor and the 40 foot trailer can haul up to 34 tons of cargo. The mission of 915 companies is to push large quantities of cargo from theater to corps level, so the light truck companies can take the smaller loads forward to the warfighters on or near the battlefield. Medium truck Platoon Leaders will deploy with their platoons as convoy commanders and OICs for some missions, but potentially will serve less time in the field than light truck Platoon Leaders.
Whether in a light, medium or light/medium company, your soldiers will often be tasked to operate around post as well, as transportation truck units are committed daily in support of garrison missions. Instilling pride, safety consciousness and active professionalism in your soldiers is a very large part of your duties as a truck Platoon Leader.
Heavy Equipment Transportation (HET) truck units serve one purpose in the Army -- they move the tanks around the battlefield for tactical or strategic advantage. The soldiers assigned to HET units are usually experienced senior enlisted ranks and NCOs. There is no garrison transportation mission for HETs, but upkeep of the equipment usually keeps the non-deployed platoons busy when out of the field.
Boat Platoon Leaders are assigned to specific locations: FT Eustis, VA; FT Story, VA; Hawaii; or Panama. Standard deployments for boat companies include Greenland, Antarctica, Honduras, and Panama. Boat Platoon Leaders do not serve as vessel commanders. On the smaller vessels, SGTs perform this function, on larger boats Warrant Officers fill these slots. The Platoon Leader ensures that missions are properly tasked, prepared for, and will deploy to ensure accomplishment, but the technical aspects of operating the vessel at sea are not his/her responsibility.
The Terminal Service and Terminal Transfer units routinely deploy to the above locations as well as Korea, Europe, the Philippines, Japan, throughout the US, and most recently, to the Middle East. Broadly put, ANY TIME the Army moves a significant amount of materiel somewhere, the Terminal units will deploy to upload at CONUS ports, then again to download at the destination port. In addition to the locations listed for the boat Platoon Leaders (minus Hawaii), terminal slots exist at FT Campbell and FT Bragg.


text:
Google+ Pages for Businesses — the Good and Bad
Google just announced that Google+ Pages for Businesses are here, finally allowing a flood of brands and celebrities to create yet another social network outlet for interacting with customers and fans. At a glance, Google+Pages is shockingly simple and seems to offer almost no difference from the standard profile all users get upon joining, but there are a few details that are bound to make things interesting (for better or worse).
Unsurprisingly, the strength of Google+ Pages lies in Circles. Businesses can designate VIPs, team members, repeat customers, and even other people/Pages that they choose to follow. Better yet, with the Circles architecture, businesses can communicate with specific subgroups of its customer base without making it publicly visible.
Google+ Pages definitely has the upper hand on Twitter by offering the same Picasa-driven album support regular users get. Google+ Pages even trumps Facebook with easily switching between Page profiles as an administrator. And who can forget Hangouts? One of Google+'s initial draws was the ability for real-time video chat with friends. Google brought the same functionality to Pages, which is an obvious advantage that Google holds over both Facebook and Twitter. Mobile Hangouts are not yet available for Pages.
Perhaps the strongest feature of Google+ Pages as of now is what Google calls Direct Connect. With Direct Connect, Google+ users can simply enter "+BusinessName" into the Google search engine, and if a Page exists for that business or celebrity, it will automatically be added to the users' Circles. Businesses with a Google+ Page will almost certainly enjoy priority indexing in classic search for users to access their Page.
Easily switch between your personal and business profiles
Being in its infant stages, Google+ Pages holds the obvious downside that there is currently no way of promoting a Page within the social network. While Pages offers tools for promoting a Google+ Page from an outside website, like badges and +1 buttons, paid advertising is still unavailable.
Another key difference between Google+ Pages and Facebook is that Pages have no way of customizing non-post content. Many companies on Facebook have created customized landing pages that would be impossible to replicate within Google+. However, Google+ has released an expanding platform API, so perhaps it's just a matter of time until Google+ Pages gets some added content flexibility.
One important issue that needs to be addressed with Google+ Pages is that there is no verification process, and just about anybody could create a profile for any business. Nab your profile before somebody else does!
A final small but annoying problem is that currently Google+ Pages only supports a single administrator per Page. If somebody finds a way to get around this, please let me know!
Limited content options for Business
The big question for businesses is how Google intends to let them easily advertise to the growing crowd of 50+ million users that Google+ has accrued in its first few months. At the moment, the ease and demographic specificity of Facebook Ads is unmatched, so it will be interesting to see how Google displays ads within Google+ and streamlines its Google Adwords platform for use in its own social network.
Google+ is now a part of Google Apps, so it's clear that Google is making a serious effort to promote Google+ as a business tool in addition to a typical social network. Google+ Pages has some ground to cover, but with promises of features being rolled out in typical Google fashion, Facebook and Twitter will have to admit there is another social player in town for businesses.
Reviews, Social Networks
Brian Nelson
businesses, Google, Social Networks
One response to "Google+ Pages for Businesses — the Good and Bad"
Evan Wondrasek
You aren't kidding about it being easy to create a Google+ page! Although I think there's some type of email verification required, but it's after the account has already been created.
I read a post from one of the Google+ devs yesterday saying that multiple admins for Pages is in the works.


text:
ATCO Electric workers work on power lines in Whitehorse. The company says it's responding to a power outage affecting downtown. (Joel Krahn/Yukon News file)
'Unplanned power outage' affecting downtown Whitehorse
Gabrielle Plonka
Nov. 8, 2021 12:00 p.m.
ATCO Electric Yukon is responding to an "unplanned outage" downtown.
ATCO and Yukon Energy announced the outage around 12 p.m. on Nov. 8.
The outage is affecting Main, Strickland and Alexander streets in the area of Second and Third avenues.
"Our crews have been notified and are responding," ATCO says in a Facebook post.
Youth panel on climate change presents conclusions to Yukon government
'Widespread community transmission' flagged in Whitehorse


If you know anyone looking for a puppy this one is perfect, she's very sweet and playful. She was dumped out at the lake and needs a forever home. We would keep her but we already have a dog and a toddler, so we won't have much time for her.
She's not house trained but she does go outside when you take her. If she does not find one for her, she will be taken to the pound. If interested contact me, and I will get in contact with her. Please share!
1 Response to "No more tears to cry, She was dumped out at the lake and needs a forever home"
Please share this little angel wherever you are!! Hope someone can foster or adopt now!!!!!!! Thank you so much for taking this little one in for now!!