Code Duplication    Length = 22-27 lines in 3 locations

comics.py 3 locations

@@ 1361-1387 (lines=27) @@
1358
class ButterSafe(GenericListableComic):
1359
    """Class to retrieve Butter Safe comics."""
1360
    name = 'butter'
1361
    long_name = 'ButterSafe'
1362
    url = 'http://buttersafe.com'
1363
    get_url_from_archive_element = get_href
1364
    comic_link_re = re.compile('^%s/([0-9]*)/([0-9]*)/([0-9]*)/.*' % url)
1365
1366
    @classmethod
1367
    def get_archive_elements(cls):
1368
        archive_url = urljoin_wrapper(cls.url, 'archive/')
1369
        return reversed(get_soup_at_url(archive_url).find_all('a', href=cls.comic_link_re))
1370
1371
    @classmethod
1372
    def get_comic_info(cls, soup, link):
1373
        """Get information about a particular comics."""
1374
        url = cls.get_url_from_archive_element(link)
1375
        title = link.string
1376
        year, month, day = [int(s) for s in cls.comic_link_re.match(url).groups()]
1377
        img = soup.find('div', id='comic').find('img')
1378
        assert img['alt'] == title
1379
        return {
1380
            'title': title,
1381
            'day': day,
1382
            'month': month,
1383
            'year': year,
1384
            'img': [img['src']],
1385
        }
1386
1387
1388
class CalvinAndHobbes(GenericComic):
1389
    """Class to retrieve Calvin and Hobbes comics."""
1390
    # Also on http://www.gocomics.com/calvinandhobbes/
@@ 1427-1448 (lines=22) @@
1424
class AbstruseGoose(GenericListableComic):
1425
    """Class to retrieve AbstruseGoose Comics."""
1426
    name = 'abstruse'
1427
    long_name = 'Abstruse Goose'
1428
    url = 'http://abstrusegoose.com'
1429
    get_url_from_archive_element = get_href
1430
    comic_url_re = re.compile('^%s/([0-9]*)$' % url)
1431
    comic_img_re = re.compile('^%s/strips/.*' % url)
1432
1433
    @classmethod
1434
    def get_archive_elements(cls):
1435
        archive_url = urljoin_wrapper(cls.url, 'archive')
1436
        return get_soup_at_url(archive_url).find_all('a', href=cls.comic_url_re)
1437
1438
    @classmethod
1439
    def get_comic_info(cls, soup, archive_elt):
1440
        comic_url = cls.get_url_from_archive_element(archive_elt)
1441
        num = int(cls.comic_url_re.match(comic_url).groups()[0])
1442
        return {
1443
            'num': num,
1444
            'title': archive_elt.string,
1445
            'img': [soup.find('img', src=cls.comic_img_re)['src']]
1446
        }
1447
1448
1449
class PhDComics(GenericNavigableComic):
1450
    """Class to retrieve PHD Comics."""
1451
    name = 'phd'
@@ 2037-2060 (lines=24) @@
2034
class PoorlyDrawnLines(GenericListableComic):
2035
    """Class to retrieve Poorly Drawn Lines comics."""
2036
    # Also on http://pdlcomics.tumblr.com
2037
    name = 'poorlydrawn'
2038
    long_name = 'Poorly Drawn Lines'
2039
    url = 'https://www.poorlydrawnlines.com'
2040
    _categories = ('POORLYDRAWN', )
2041
    get_url_from_archive_element = get_href
2042
2043
    @classmethod
2044
    def get_comic_info(cls, soup, link):
2045
        """Get information about a particular comics."""
2046
        imgs = soup.find('div', class_='post').find_all('img')
2047
        assert len(imgs) <= 1
2048
        return {
2049
            'img': [i['src'] for i in imgs],
2050
            'title': imgs[0].get('title', "") if imgs else "",
2051
        }
2052
2053
    @classmethod
2054
    def get_archive_elements(cls):
2055
        archive_url = urljoin_wrapper(cls.url, 'archive')
2056
        url_re = re.compile('^%s/comic/.' % cls.url)
2057
        return reversed(get_soup_at_url(archive_url).find_all('a', href=url_re))
2058
2059
2060
class LoadingComics(GenericNavigableComic):
2061
    """Class to retrieve Loading Artist comics."""
2062
    name = 'loadingartist'
2063
    long_name = 'Loading Artist'