Code Duplication    Length = 23-27 lines in 3 locations

comics.py 3 locations

@@ 1407-1433 (lines=27) @@
1404
class ButterSafe(GenericListableComic):
1405
    """Class to retrieve Butter Safe comics."""
1406
    name = 'butter'
1407
    long_name = 'ButterSafe'
1408
    url = 'http://buttersafe.com'
1409
    get_url_from_archive_element = get_href
1410
    comic_link_re = re.compile('^%s/([0-9]*)/([0-9]*)/([0-9]*)/.*' % url)
1411
1412
    @classmethod
1413
    def get_archive_elements(cls):
1414
        archive_url = urljoin_wrapper(cls.url, 'archive/')
1415
        return reversed(get_soup_at_url(archive_url).find_all('a', href=cls.comic_link_re))
1416
1417
    @classmethod
1418
    def get_comic_info(cls, soup, link):
1419
        """Get information about a particular comics."""
1420
        url = cls.get_url_from_archive_element(link)
1421
        title = link.string
1422
        year, month, day = [int(s) for s in cls.comic_link_re.match(url).groups()]
1423
        img = soup.find('div', id='comic').find('img')
1424
        assert img['alt'] == title
1425
        return {
1426
            'title': title,
1427
            'day': day,
1428
            'month': month,
1429
            'year': year,
1430
            'img': [img['src']],
1431
        }
1432
1433
1434
class CalvinAndHobbes(GenericComic):
1435
    """Class to retrieve Calvin and Hobbes comics."""
1436
    # Also on http://www.gocomics.com/calvinandhobbes/
@@ 1473-1495 (lines=23) @@
1470
class AbstruseGoose(GenericListableComic):
1471
    """Class to retrieve AbstruseGoose Comics."""
1472
    name = 'abstruse'
1473
    long_name = 'Abstruse Goose'
1474
    url = 'http://abstrusegoose.com'
1475
    get_url_from_archive_element = get_href
1476
    comic_url_re = re.compile('^%s/([0-9]*)$' % url)
1477
    comic_img_re = re.compile('^%s/strips/.*' % url)
1478
1479
    @classmethod
1480
    def get_archive_elements(cls):
1481
        archive_url = urljoin_wrapper(cls.url, 'archive')
1482
        return get_soup_at_url(archive_url).find_all('a', href=cls.comic_url_re)
1483
1484
    @classmethod
1485
    def get_comic_info(cls, soup, archive_elt):
1486
        comic_url = cls.get_url_from_archive_element(archive_elt)
1487
        num = int(cls.comic_url_re.match(comic_url).groups()[0])
1488
        imgs = soup.find_all('img', src=cls.comic_img_re)
1489
        return {
1490
            'num': num,
1491
            'title': archive_elt.string,
1492
            'img': [i['src'] for i in imgs],
1493
        }
1494
1495
1496
class PhDComics(GenericNavigableComic):
1497
    """Class to retrieve PHD Comics."""
1498
    name = 'phd'
@@ 2374-2398 (lines=25) @@
2371
class JuliasDrawings(GenericListableComic):
2372
    """Class to retrieve Julia's Drawings."""
2373
    name = 'julia'
2374
    long_name = "Julia's Drawings"
2375
    url = 'https://drawings.jvns.ca'
2376
    get_url_from_archive_element = get_href
2377
2378
    @classmethod
2379
    def get_archive_elements(cls):
2380
        div = get_soup_at_url(cls.url).find('div', class_='drawings')
2381
        return reversed(div.find_all('a'))
2382
2383
    @classmethod
2384
    def get_comic_info(cls, soup, archive_elt):
2385
        """Get information about a particular comics."""
2386
        date_str = soup.find('meta', property='og:article:published_time')['content'][:10]
2387
        day = string_to_date(date_str, "%Y-%m-%d")
2388
        title = soup.find('h3', class_='p-post-title').string
2389
        imgs = soup.find('section', class_='post-content').find_all('img')
2390
        return {
2391
            'title': title,
2392
            'img': [urljoin_wrapper(cls.url, i['src']) for i in imgs],
2393
            'month': day.month,
2394
            'year': day.year,
2395
            'day': day.day,
2396
        }
2397
2398
2399
class AnythingComic(GenericListableComic):
2400
    """Class to retrieve Anything Comics."""
2401
    # Also on http://tapastic.com/series/anything