Code Duplication    Length = 21-29 lines in 25 locations

comics.py 25 locations

@@ 1861-1887 (lines=27) @@
1858
        }
1859
1860
1861
class PicturesInBoxes(GenericNavigableComic):
1862
    """Class to retrieve Pictures In Boxes comics."""
1863
    # Also on https://picturesinboxescomic.tumblr.com
1864
    name = 'picturesinboxes'
1865
    long_name = 'Pictures in Boxes'
1866
    url = 'http://www.picturesinboxes.com'
1867
    get_navi_link = get_a_navi_navinext
1868
    get_first_comic_link = simulate_first_link
1869
    first_url = 'http://www.picturesinboxes.com/2013/10/26/tetris/'
1870
1871
    @classmethod
1872
    def get_comic_info(cls, soup, link):
1873
        """Get information about a particular comics."""
1874
        title = soup.find('h2', class_='post-title').string
1875
        author = soup.find("span", class_="post-author").find("a").string
1876
        date_str = soup.find('span', class_='post-date').string
1877
        day = string_to_date(date_str, '%B %d, %Y')
1878
        imgs = soup.find('div', class_='comicpane').find_all('img')
1879
        assert imgs
1880
        assert all(i['title'] == i['alt'] == title for i in imgs)
1881
        return {
1882
            'day': day.day,
1883
            'month': day.month,
1884
            'year': day.year,
1885
            'img': [i['src'] for i in imgs],
1886
            'title': title,
1887
            'author': author,
1888
        }
1889
1890
@@ 928-954 (lines=27) @@
925
        }
926
927
928
class ImogenQuest(GenericNavigableComic):
929
    """Class to retrieve Imogen Quest comics."""
930
    # Also on http://imoquest.tumblr.com
931
    name = 'imogen'
932
    long_name = 'Imogen Quest'
933
    url = 'http://imogenquest.net'
934
    get_first_comic_link = get_div_navfirst_a
935
    get_navi_link = get_a_rel_next
936
937
    @classmethod
938
    def get_comic_info(cls, soup, link):
939
        """Get information about a particular comics."""
940
        title = soup.find('h2', class_='post-title').string
941
        author = soup.find("span", class_="post-author").find("a").string
942
        date_str = soup.find('span', class_='post-date').string
943
        day = string_to_date(date_str, '%B %d, %Y')
944
        imgs = soup.find('div', class_='comicpane').find_all('img')
945
        assert all(i['alt'] == i['title'] for i in imgs)
946
        title2 = imgs[0]['title']
947
        return {
948
            'day': day.day,
949
            'month': day.month,
950
            'year': day.year,
951
            'img': [i['src'] for i in imgs],
952
            'title': title,
953
            'title2': title2,
954
            'author': author,
955
        }
956
957
@@ 2534-2559 (lines=26) @@
2531
        }
2532
2533
2534
class TheAwkwardYeti(GenericNavigableComic):
2535
    """Class to retrieve The Awkward Yeti comics."""
2536
    # Also on http://www.gocomics.com/the-awkward-yeti
2537
    # Also on http://larstheyeti.tumblr.com
2538
    # Also on https://tapastic.com/series/TheAwkwardYeti
2539
    name = 'yeti'
2540
    long_name = 'The Awkward Yeti'
2541
    url = 'http://theawkwardyeti.com'
2542
    _categories = ('YETI', )
2543
    get_first_comic_link = get_a_navi_navifirst
2544
    get_navi_link = get_link_rel_next
2545
2546
    @classmethod
2547
    def get_comic_info(cls, soup, link):
2548
        """Get information about a particular comics."""
2549
        title = soup.find('h2', class_='post-title').string
2550
        date_str = soup.find("span", class_="post-date").string
2551
        day = string_to_date(date_str, "%B %d, %Y")
2552
        imgs = soup.find("div", id="comic").find_all("img")
2553
        assert all(idx > 0 or i['alt'] == i['title'] for idx, i in enumerate(imgs))
2554
        return {
2555
            'img': [i['src'] for i in imgs],
2556
            'title': title,
2557
            'day': day.day,
2558
            'month': day.month,
2559
            'year': day.year
2560
        }
2561
2562
@@ 2788-2812 (lines=25) @@
2785
    first_url = 'http://www.commitstrip.com/en/2012/02/22/interview/'
2786
2787
2788
class GenericBoumerie(GenericNavigableComic):
2789
    """Generic class to retrieve Boumeries comics in different languages."""
2790
    get_first_comic_link = get_a_navi_navifirst
2791
    get_navi_link = get_link_rel_next
2792
    date_format = NotImplemented
2793
    lang = NotImplemented
2794
2795
    @classmethod
2796
    def get_comic_info(cls, soup, link):
2797
        """Get information about a particular comics."""
2798
        title = soup.find('h2', class_='post-title').string
2799
        short_url = soup.find('link', rel='shortlink')['href']
2800
        author = soup.find("span", class_="post-author").find("a").string
2801
        date_str = soup.find('span', class_='post-date').string
2802
        day = string_to_date(date_str, cls.date_format, cls.lang)
2803
        imgs = soup.find('div', id='comic').find_all('img')
2804
        assert all(i['alt'] == i['title'] for i in imgs)
2805
        return {
2806
            'short_url': short_url,
2807
            'img': [i['src'] for i in imgs],
2808
            'title': title,
2809
            'author': author,
2810
            'month': day.month,
2811
            'year': day.year,
2812
            'day': day.day,
2813
        }
2814
2815
@@ 2476-2500 (lines=25) @@
2473
        }
2474
2475
2476
class EveryDayBlues(GenericEmptyComic, GenericNavigableComic):
2477
    """Class to retrieve EveryDayBlues Comics."""
2478
    name = "blues"
2479
    long_name = "Every Day Blues"
2480
    url = "http://everydayblues.net"
2481
    get_first_comic_link = get_a_navi_navifirst
2482
    get_navi_link = get_link_rel_next
2483
2484
    @classmethod
2485
    def get_comic_info(cls, soup, link):
2486
        """Get information about a particular comics."""
2487
        title = soup.find("h2", class_="post-title").string
2488
        author = soup.find("span", class_="post-author").find("a").string
2489
        date_str = soup.find("span", class_="post-date").string
2490
        day = string_to_date(date_str, "%d. %B %Y", "de_DE.utf8")
2491
        imgs = soup.find("div", id="comic").find_all("img")
2492
        assert all(i['alt'] == i['title'] == title for i in imgs)
2493
        assert len(imgs) <= 1
2494
        return {
2495
            'img': [i['src'] for i in imgs],
2496
            'title': title,
2497
            'author': author,
2498
            'day': day.day,
2499
            'month': day.month,
2500
            'year': day.year
2501
        }
2502
2503
@@ 1749-1773 (lines=25) @@
1746
        }
1747
1748
1749
class MouseBearComedy(GenericNavigableComic):
1750
    """Class to retrieve Mouse Bear Comedy comics."""
1751
    # Also on http://mousebearcomedy.tumblr.com
1752
    name = 'mousebear'
1753
    long_name = 'Mouse Bear Comedy'
1754
    url = 'http://www.mousebearcomedy.com'
1755
    get_first_comic_link = get_a_navi_navifirst
1756
    get_navi_link = get_a_navi_comicnavnext_navinext
1757
1758
    @classmethod
1759
    def get_comic_info(cls, soup, link):
1760
        """Get information about a particular comics."""
1761
        title = soup.find('h2', class_='post-title').string
1762
        author = soup.find("span", class_="post-author").find("a").string
1763
        date_str = soup.find("span", class_="post-date").string
1764
        day = string_to_date(date_str, '%B %d, %Y')
1765
        imgs = soup.find("div", id="comic").find_all("img")
1766
        assert all(i['alt'] == i['title'] == title for i in imgs)
1767
        return {
1768
            'day': day.day,
1769
            'month': day.month,
1770
            'year': day.year,
1771
            'img': [i['src'] for i in imgs],
1772
            'title': title,
1773
            'author': author,
1774
        }
1775
1776
@@ 1157-1180 (lines=24) @@
1154
    url = 'http://english.bouletcorp.com'
1155
1156
1157
class AmazingSuperPowers(GenericNavigableComic):
1158
    """Class to retrieve Amazing Super Powers comics."""
1159
    name = 'asp'
1160
    long_name = 'Amazing Super Powers'
1161
    url = 'http://www.amazingsuperpowers.com'
1162
    get_first_comic_link = get_a_navi_navifirst
1163
    get_navi_link = get_a_navi_navinext
1164
1165
    @classmethod
1166
    def get_comic_info(cls, soup, link):
1167
        """Get information about a particular comics."""
1168
        author = soup.find("span", class_="post-author").find("a").string
1169
        date_str = soup.find('span', class_='post-date').string
1170
        day = string_to_date(date_str, "%B %d, %Y")
1171
        imgs = soup.find('div', id='comic').find_all('img')
1172
        title = ' '.join(i['title'] for i in imgs)
1173
        assert all(i['alt'] == i['title'] for i in imgs)
1174
        return {
1175
            'title': title,
1176
            'author': author,
1177
            'img': [img['src'] for img in imgs],
1178
            'day': day.day,
1179
            'month': day.month,
1180
            'year': day.year
1181
        }
1182
1183
@@ 674-697 (lines=24) @@
671
        }
672
673
674
class OneOneOneOneComic(GenericEmptyComic, GenericNavigableComic):
675
    """Class to retrieve 1111 Comics."""
676
    # Also on http://comics1111.tumblr.com
677
    # Also on https://tapastic.com/series/1111-Comics
678
    name = '1111'
679
    long_name = '1111 Comics'
680
    url = 'http://www.1111comics.me'
681
    _categories = ('ONEONEONEONE', )
682
    get_first_comic_link = get_div_navfirst_a
683
    get_navi_link = get_link_rel_next
684
685
    @classmethod
686
    def get_comic_info(cls, soup, link):
687
        """Get information about a particular comics."""
688
        title = soup.find('h1', class_='comic-title').find('a').string
689
        date_str = soup.find('header', class_='comic-meta entry-meta').find('a').string
690
        day = string_to_date(date_str, "%B %d, %Y")
691
        imgs = soup.find_all('meta', property='og:image')
692
        return {
693
            'title': title,
694
            'month': day.month,
695
            'year': day.year,
696
            'day': day.day,
697
            'img': [i['content'] for i in imgs],
698
        }
699
700
@@ 902-924 (lines=23) @@
899
        }
900
901
902
class TheGentlemanArmchair(GenericNavigableComic):
903
    """Class to retrieve The Gentleman Armchair comics."""
904
    name = 'gentlemanarmchair'
905
    long_name = 'The Gentleman Armchair'
906
    url = 'http://thegentlemansarmchair.com'
907
    get_first_comic_link = get_a_navi_navifirst
908
    get_navi_link = get_link_rel_next
909
910
    @classmethod
911
    def get_comic_info(cls, soup, link):
912
        """Get information about a particular comics."""
913
        title = soup.find('h2', class_='post-title').string
914
        author = soup.find("span", class_="post-author").find("a").string
915
        date_str = soup.find('span', class_='post-date').string
916
        day = string_to_date(date_str, "%B %d, %Y")
917
        imgs = soup.find('div', id='comic').find_all('img')
918
        return {
919
            'img': [i['src'] for i in imgs],
920
            'title': title,
921
            'author': author,
922
            'month': day.month,
923
            'year': day.year,
924
            'day': day.day,
925
        }
926
927
@@ 701-722 (lines=22) @@
698
        }
699
700
701
class AngryAtNothing(GenericEmptyComic, GenericNavigableComic):
702
    """Class to retrieve Angry at Nothing comics."""
703
    # Also on http://tapastic.com/series/Comics-yeah-definitely-comics-
704
    # Also on http://angryatnothing.tumblr.com
705
    name = 'angry'
706
    long_name = 'Angry At Nothing'
707
    url = 'http://www.angryatnothing.net'
708
    get_first_comic_link = get_div_navfirst_a
709
    get_navi_link = get_a_rel_next
710
711
    @classmethod
712
    def get_comic_info(cls, soup, link):
713
        """Get information about a particular comics."""
714
        title = soup.find('h1', class_='comic-title').find('a').string
715
        date_str = soup.find('header', class_='comic-meta entry-meta').find('a').string
716
        day = string_to_date(date_str, "%B %d, %Y")
717
        imgs = soup.find_all('meta', property='og:image')
718
        return {
719
            'title': title,
720
            'month': day.month,
721
            'year': day.year,
722
            'day': day.day,
723
            'img': [i['content'] for i in imgs],
724
        }
725
@@ 2645-2673 (lines=29) @@
2642
        }
2643
2644
2645
class TalesOfAbsurdity(GenericNavigableComic):
2646
    """Class to retrieve Tales Of Absurdity comics."""
2647
    # Also on http://tapastic.com/series/Tales-Of-Absurdity
2648
    # Also on http://talesofabsurdity.tumblr.com
2649
    name = 'absurdity'
2650
    long_name = 'Tales of Absurdity'
2651
    url = 'http://talesofabsurdity.com'
2652
    _categories = ('ABSURDITY', )
2653
    get_first_comic_link = get_a_navi_navifirst
2654
    get_navi_link = get_a_navi_comicnavnext_navinext
2655
2656
    @classmethod
2657
    def get_comic_info(cls, soup, link):
2658
        """Get information about a particular comics."""
2659
        title = soup.find('h2', class_='post-title').string
2660
        author = soup.find("span", class_="post-author").find("a").string
2661
        date_str = soup.find("span", class_="post-date").string
2662
        day = string_to_date(date_str, "%B %d, %Y")
2663
        imgs = soup.find("div", id="comic").find_all("img")
2664
        assert all(i['alt'] == i['title'] for i in imgs)
2665
        alt = imgs[0]['alt'] if imgs else ""
2666
        return {
2667
            'img': [i['src'] for i in imgs],
2668
            'title': title,
2669
            'alt': alt,
2670
            'author': author,
2671
            'day': day.day,
2672
            'month': day.month,
2673
            'year': day.year
2674
        }
2675
2676
@@ 2869-2895 (lines=27) @@
2866
        }
2867
2868
2869
class Optipess(GenericNavigableComic):
2870
    """Class to retrieve Optipess comics."""
2871
    name = 'optipess'
2872
    long_name = 'Optipess'
2873
    url = 'http://www.optipess.com'
2874
    get_first_comic_link = get_a_navi_navifirst
2875
    get_navi_link = get_link_rel_next
2876
2877
    @classmethod
2878
    def get_comic_info(cls, soup, link):
2879
        """Get information about a particular comics."""
2880
        title = soup.find('h2', class_='post-title').string
2881
        author = soup.find("span", class_="post-author").find("a").string
2882
        comic = soup.find('div', id='comic')
2883
        imgs = comic.find_all('img') if comic else []
2884
        alt = imgs[0]['title'] if imgs else ""
2885
        assert all(i['alt'] == i['title'] == alt for i in imgs)
2886
        date_str = soup.find('span', class_='post-date').string
2887
        day = string_to_date(date_str, "%B %d, %Y")
2888
        return {
2889
            'title': title,
2890
            'alt': alt,
2891
            'author': author,
2892
            'img': [i['src'] for i in imgs],
2893
            'month': day.month,
2894
            'year': day.year,
2895
            'day': day.day,
2896
        }
2897
2898
@@ 2504-2530 (lines=27) @@
2501
        }
2502
2503
2504
class BiterComics(GenericNavigableComic):
2505
    """Class to retrieve Biter Comics."""
2506
    name = "biter"
2507
    long_name = "Biter Comics"
2508
    url = "http://www.bitercomics.com"
2509
    get_first_comic_link = get_a_navi_navifirst
2510
    get_navi_link = get_link_rel_next
2511
2512
    @classmethod
2513
    def get_comic_info(cls, soup, link):
2514
        """Get information about a particular comics."""
2515
        title = soup.find("h1", class_="entry-title").string
2516
        author = soup.find("span", class_="author vcard").find("a").string
2517
        date_str = soup.find("span", class_="entry-date").string
2518
        day = string_to_date(date_str, "%B %d, %Y")
2519
        imgs = soup.find("div", id="comic").find_all("img")
2520
        assert all(i['alt'] == i['title'] for i in imgs)
2521
        assert len(imgs) == 1
2522
        alt = imgs[0]['alt']
2523
        return {
2524
            'img': [i['src'] for i in imgs],
2525
            'title': title,
2526
            'alt': alt,
2527
            'author': author,
2528
            'day': day.day,
2529
            'month': day.month,
2530
            'year': day.year
2531
        }
2532
2533
@@ 2006-2032 (lines=27) @@
2003
    _categories = ('TUNEYTOONS', )
2004
2005
2006
class CompletelySeriousComics(GenericNavigableComic):
2007
    """Class to retrieve Completely Serious comics."""
2008
    name = 'completelyserious'
2009
    long_name = 'Completely Serious Comics'
2010
    url = 'http://completelyseriouscomics.com'
2011
    get_first_comic_link = get_a_navi_navifirst
2012
    get_navi_link = get_a_navi_navinext
2013
2014
    @classmethod
2015
    def get_comic_info(cls, soup, link):
2016
        """Get information about a particular comics."""
2017
        title = soup.find('h2', class_='post-title').string
2018
        author = soup.find('span', class_='post-author').contents[1].string
2019
        date_str = soup.find('span', class_='post-date').string
2020
        day = string_to_date(date_str, '%B %d, %Y')
2021
        imgs = soup.find('div', class_='comicpane').find_all('img')
2022
        assert imgs
2023
        alt = imgs[0]['title']
2024
        assert all(i['title'] == i['alt'] == alt for i in imgs)
2025
        return {
2026
            'month': day.month,
2027
            'year': day.year,
2028
            'day': day.day,
2029
            'img': [i['src'] for i in imgs],
2030
            'title': title,
2031
            'alt': alt,
2032
            'author': author,
2033
        }
2034
2035
@@ 2677-2702 (lines=26) @@
2674
        }
2675
2676
2677
class EndlessOrigami(GenericEmptyComic, GenericNavigableComic):
2678
    """Class to retrieve Endless Origami Comics."""
2679
    name = "origami"
2680
    long_name = "Endless Origami"
2681
    url = "http://endlessorigami.com"
2682
    get_first_comic_link = get_a_navi_navifirst
2683
    get_navi_link = get_link_rel_next
2684
2685
    @classmethod
2686
    def get_comic_info(cls, soup, link):
2687
        """Get information about a particular comics."""
2688
        title = soup.find('h2', class_='post-title').string
2689
        author = soup.find("span", class_="post-author").find("a").string
2690
        date_str = soup.find("span", class_="post-date").string
2691
        day = string_to_date(date_str, "%B %d, %Y")
2692
        imgs = soup.find("div", id="comic").find_all("img")
2693
        assert all(i['alt'] == i['title'] for i in imgs)
2694
        alt = imgs[0]['alt'] if imgs else ""
2695
        return {
2696
            'img': [i['src'] for i in imgs],
2697
            'title': title,
2698
            'alt': alt,
2699
            'author': author,
2700
            'day': day.day,
2701
            'month': day.month,
2702
            'year': day.year
2703
        }
2704
2705
@@ 2218-2243 (lines=26) @@
2215
        return reversed(get_soup_at_url(archive_url).find('tbody').find_all('tr'))
2216
2217
2218
class HappleTea(GenericNavigableComic):
2219
    """Class to retrieve Happle Tea Comics."""
2220
    name = 'happletea'
2221
    long_name = 'Happle Tea'
2222
    url = 'http://www.happletea.com'
2223
    get_first_comic_link = get_a_navi_navifirst
2224
    get_navi_link = get_link_rel_next
2225
2226
    @classmethod
2227
    def get_comic_info(cls, soup, link):
2228
        """Get information about a particular comics."""
2229
        imgs = soup.find('div', id='comic').find_all('img')
2230
        post = soup.find('div', class_='post-content')
2231
        title = post.find('h2', class_='post-title').string
2232
        author = post.find('a', rel='author').string
2233
        date_str = post.find('span', class_='post-date').string
2234
        day = string_to_date(date_str, "%B %d, %Y")
2235
        assert all(i['alt'] == i['title'] for i in imgs)
2236
        return {
2237
            'title': title,
2238
            'img': [i['src'] for i in imgs],
2239
            'alt': ''.join(i['alt'] for i in imgs),
2240
            'month': day.month,
2241
            'year': day.year,
2242
            'day': day.day,
2243
            'author': author,
2244
        }
2245
2246
@@ 1891-1916 (lines=26) @@
1888
        }
1889
1890
1891
class Penmen(GenericNavigableComic):
1892
    """Class to retrieve Penmen comics."""
1893
    name = 'penmen'
1894
    long_name = 'Penmen'
1895
    url = 'http://penmen.com'
1896
    get_navi_link = get_link_rel_next
1897
    get_first_comic_link = simulate_first_link
1898
    first_url = 'http://penmen.com/index.php/2016/09/12/penmen-announces-grin-big-brand-clothing/'
1899
1900
    @classmethod
1901
    def get_comic_info(cls, soup, link):
1902
        """Get information about a particular comics."""
1903
        title = soup.find('title').string
1904
        imgs = soup.find('div', class_='entry-content').find_all('img')
1905
        short_url = soup.find('link', rel='shortlink')['href']
1906
        tags = ' '.join(t.string for t in soup.find_all('a', rel='tag'))
1907
        date_str = soup.find('time')['datetime'][:10]
1908
        day = string_to_date(date_str, "%Y-%m-%d")
1909
        return {
1910
            'title': title,
1911
            'short_url': short_url,
1912
            'img': [i['src'] for i in imgs],
1913
            'tags': tags,
1914
            'month': day.month,
1915
            'year': day.year,
1916
            'day': day.day,
1917
        }
1918
1919
@@ 1832-1857 (lines=26) @@
1829
        }
1830
1831
1832
class SafelyEndangered(GenericNavigableComic):
1833
    """Class to retrieve Safely Endangered comics."""
1834
    # Also on http://tumblr.safelyendangered.com
1835
    name = 'endangered'
1836
    long_name = 'Safely Endangered'
1837
    url = 'http://www.safelyendangered.com'
1838
    get_navi_link = get_link_rel_next
1839
    get_first_comic_link = simulate_first_link
1840
    first_url = 'http://www.safelyendangered.com/comic/ignored/'
1841
1842
    @classmethod
1843
    def get_comic_info(cls, soup, link):
1844
        """Get information about a particular comics."""
1845
        title = soup.find('h2', class_='post-title').string
1846
        date_str = soup.find('span', class_='post-date').string
1847
        day = string_to_date(date_str, '%B %d, %Y')
1848
        imgs = soup.find('div', id='comic').find_all('img')
1849
        alt = imgs[0]['alt']
1850
        assert all(i['alt'] == i['title'] for i in imgs)
1851
        return {
1852
            'day': day.day,
1853
            'month': day.month,
1854
            'year': day.year,
1855
            'img': [i['src'] for i in imgs],
1856
            'title': title,
1857
            'alt': alt,
1858
        }
1859
1860
@@ 2346-2370 (lines=25) @@
2343
        }
2344
2345
2346
class LonnieMillsap(GenericNavigableComic):
2347
    """Class to retrieve Lonnie Millsap's comics."""
2348
    name = 'millsap'
2349
    long_name = 'Lonnie Millsap'
2350
    url = 'http://www.lonniemillsap.com'
2351
    get_navi_link = get_link_rel_next
2352
    get_first_comic_link = simulate_first_link
2353
    first_url = 'http://www.lonniemillsap.com/?p=42'
2354
2355
    @classmethod
2356
    def get_comic_info(cls, soup, link):
2357
        """Get information about a particular comics."""
2358
        title = soup.find('h2', class_='post-title').string
2359
        post = soup.find('div', class_='post-content')
2360
        author = post.find("span", class_="post-author").find("a").string
2361
        date_str = post.find("span", class_="post-date").string
2362
        day = string_to_date(date_str, "%B %d, %Y")
2363
        imgs = post.find("div", class_="entry").find_all("img")
2364
        return {
2365
            'title': title,
2366
            'author': author,
2367
            'img': [i['src'] for i in imgs],
2368
            'month': day.month,
2369
            'year': day.year,
2370
            'day': day.day,
2371
        }
2372
2373
@@ 2094-2118 (lines=25) @@
2091
        }
2092
2093
2094
class ChuckleADuck(GenericNavigableComic):
2095
    """Class to retrieve Chuckle-A-Duck comics."""
2096
    name = 'chuckleaduck'
2097
    long_name = 'Chuckle-A-duck'
2098
    url = 'http://chuckleaduck.com'
2099
    get_first_comic_link = get_div_navfirst_a
2100
    get_navi_link = get_link_rel_next
2101
2102
    @classmethod
2103
    def get_comic_info(cls, soup, link):
2104
        """Get information about a particular comics."""
2105
        date_str = soup.find('span', class_='post-date').string
2106
        day = string_to_date(remove_st_nd_rd_th_from_date(date_str), "%B %d, %Y")
2107
        author = soup.find('span', class_='post-author').string
2108
        div = soup.find('div', id='comic')
2109
        imgs = div.find_all('img') if div else []
2110
        title = imgs[0]['title'] if imgs else ""
2111
        assert all(i['title'] == i['alt'] == title for i in imgs)
2112
        return {
2113
            'month': day.month,
2114
            'year': day.year,
2115
            'day': day.day,
2116
            'img': [i['src'] for i in imgs],
2117
            'title': title,
2118
            'author': author,
2119
        }
2120
2121
@@ 3156-3179 (lines=24) @@
3153
        }
3154
3155
3156
class Ubertool(GenericNavigableComic):
3157
    """Class to retrieve Ubertool comics."""
3158
    # Also on https://ubertool.tumblr.com
3159
    # Also on https://tapastic.com/series/ubertool
3160
    name = 'ubertool'
3161
    long_name = 'Ubertool'
3162
    url = 'http://ubertoolcomic.com'
3163
    _categories = ('UBERTOOL', )
3164
    get_first_comic_link = get_a_comicnavbase_comicnavfirst
3165
    get_navi_link = get_a_comicnavbase_comicnavnext
3166
3167
    @classmethod
3168
    def get_comic_info(cls, soup, link):
3169
        """Get information about a particular comics."""
3170
        title = soup.find('h2', class_='post-title').string
3171
        date_str = soup.find('span', class_='post-date').string
3172
        day = string_to_date(date_str, "%B %d, %Y")
3173
        imgs = soup.find('div', id='comic').find_all('img')
3174
        return {
3175
            'img': [i['src'] for i in imgs],
3176
            'title': title,
3177
            'month': day.month,
3178
            'year': day.year,
3179
            'day': day.day,
3180
        }
3181
3182
@@ 648-670 (lines=23) @@
645
        }
646
647
648
class PenelopeBagieu(GenericNavigableComic):
649
    """Class to retrieve comics from Penelope Bagieu's blog."""
650
    name = 'bagieu'
651
    long_name = 'Ma vie est tout a fait fascinante (Bagieu)'
652
    url = 'http://www.penelope-jolicoeur.com'
653
    _categories = ('FRANCAIS', )
654
    get_navi_link = get_link_rel_next
655
    get_first_comic_link = simulate_first_link
656
    first_url = 'http://www.penelope-jolicoeur.com/2007/02/ma-vie-mon-oeuv.html'
657
658
    @classmethod
659
    def get_comic_info(cls, soup, link):
660
        """Get information about a particular comics."""
661
        date_str = soup.find('h2', class_='date-header').string
662
        day = string_to_date(date_str, "%A %d %B %Y", "fr_FR.utf8")
663
        imgs = soup.find('div', class_='entry-body').find_all('img')
664
        title = soup.find('h3', class_='entry-header').string
665
        return {
666
            'title': title,
667
            'img': [i['src'] for i in imgs],
668
            'month': day.month,
669
            'year': day.year,
670
            'day': day.day,
671
        }
672
673
@@ 1702-1722 (lines=21) @@
1699
        }
1700
1701
1702
class WarehouseComic(GenericNavigableComic):
1703
    """Class to retrieve Warehouse Comic comics."""
1704
    name = 'warehouse'
1705
    long_name = 'Warehouse Comic'
1706
    url = 'http://warehousecomic.com'
1707
    get_first_comic_link = get_a_navi_navifirst
1708
    get_navi_link = get_link_rel_next
1709
1710
    @classmethod
1711
    def get_comic_info(cls, soup, link):
1712
        """Get information about a particular comics."""
1713
        title = soup.find('h2', class_='post-title').string
1714
        date_str = soup.find('span', class_='post-date').string
1715
        day = string_to_date(date_str, "%B %d, %Y")
1716
        imgs = soup.find('div', id='comic').find_all('img')
1717
        return {
1718
            'img': [i['src'] for i in imgs],
1719
            'title': title,
1720
            'day': day.day,
1721
            'month': day.month,
1722
            'year': day.year,
1723
        }
1724
1725
@@ 2583-2611 (lines=29) @@
2580
        }
2581
2582
2583
class MisterAndMe(GenericNavigableComic):
2584
    """Class to retrieve Mister & Me Comics."""
2585
    # Also on http://www.gocomics.com/mister-and-me
2586
    # Also on https://tapastic.com/series/Mister-and-Me
2587
    name = 'mister'
2588
    long_name = 'Mister & Me'
2589
    url = 'http://www.mister-and-me.com'
2590
    get_first_comic_link = get_a_comicnavbase_comicnavfirst
2591
    get_navi_link = get_link_rel_next
2592
2593
    @classmethod
2594
    def get_comic_info(cls, soup, link):
2595
        """Get information about a particular comics."""
2596
        title = soup.find('h2', class_='post-title').string
2597
        author = soup.find("span", class_="post-author").find("a").string
2598
        date_str = soup.find("span", class_="post-date").string
2599
        day = string_to_date(date_str, "%B %d, %Y")
2600
        imgs = soup.find("div", id="comic").find_all("img")
2601
        assert all(i['alt'] == i['title'] for i in imgs)
2602
        assert len(imgs) <= 1
2603
        alt = imgs[0]['alt'] if imgs else ""
2604
        return {
2605
            'img': [i['src'] for i in imgs],
2606
            'title': title,
2607
            'alt': alt,
2608
            'author': author,
2609
            'day': day.day,
2610
            'month': day.month,
2611
            'year': day.year
2612
        }
2613
2614
@@ 360-382 (lines=23) @@
357
        return []
358
359
360
class ExtraFabulousComics(GenericNavigableComic):
361
    """Class to retrieve Extra Fabulous Comics."""
362
    name = 'efc'
363
    long_name = 'Extra Fabulous Comics'
364
    url = 'http://extrafabulouscomics.com'
365
    get_first_comic_link = get_a_navi_navifirst
366
    get_navi_link = get_link_rel_next
367
368
    @classmethod
369
    def get_comic_info(cls, soup, link):
370
        """Get information about a particular comics."""
371
        img_src_re = re.compile('^%s/wp-content/uploads/' % cls.url)
372
        imgs = soup.find_all('img', src=img_src_re)
373
        title = soup.find('meta', property='og:title')['content']
374
        date_str = soup.find('meta', property='article:published_time')['content'][:10]
375
        day = string_to_date(date_str, "%Y-%m-%d")
376
        return {
377
            'title': title,
378
            'img': [i['src'] for i in imgs],
379
            'month': day.month,
380
            'year': day.year,
381
            'day': day.day,
382
            'prefix': title + '-'
383
        }
384
385