Code Duplication    Length = 21-29 lines in 23 locations

comics.py 23 locations

@@ 1888-1914 (lines=27) @@
1885
1886
class PicturesInBoxes(GenericNavigableComic):
1887
    """Class to retrieve Pictures In Boxes comics."""
1888
    # Also on https://picturesinboxescomic.tumblr.com
1889
    name = 'picturesinboxes'
1890
    long_name = 'Pictures in Boxes'
1891
    url = 'http://www.picturesinboxes.com'
1892
    get_navi_link = get_a_navi_navinext
1893
    get_first_comic_link = simulate_first_link
1894
    first_url = 'http://www.picturesinboxes.com/2013/10/26/tetris/'
1895
1896
    @classmethod
1897
    def get_comic_info(cls, soup, link):
1898
        """Get information about a particular comics."""
1899
        title = soup.find('h2', class_='post-title').string
1900
        author = soup.find("span", class_="post-author").find("a").string
1901
        date_str = soup.find('span', class_='post-date').string
1902
        day = string_to_date(date_str, '%B %d, %Y')
1903
        imgs = soup.find('div', class_='comicpane').find_all('img')
1904
        assert imgs
1905
        assert all(i['title'] == i['alt'] == title for i in imgs)
1906
        return {
1907
            'day': day.day,
1908
            'month': day.month,
1909
            'year': day.year,
1910
            'img': [i['src'] for i in imgs],
1911
            'title': title,
1912
            'author': author,
1913
        }
1914
1915
1916
class Penmen(GenericNavigableComic):
1917
    """Class to retrieve Penmen comics."""
@@ 955-981 (lines=27) @@
952
        }
953
954
955
class ImogenQuest(GenericNavigableComic):
956
    """Class to retrieve Imogen Quest comics."""
957
    # Also on http://imoquest.tumblr.com
958
    name = 'imogen'
959
    long_name = 'Imogen Quest'
960
    url = 'http://imogenquest.net'
961
    get_first_comic_link = get_div_navfirst_a
962
    get_navi_link = get_a_rel_next
963
964
    @classmethod
965
    def get_comic_info(cls, soup, link):
966
        """Get information about a particular comics."""
967
        title = soup.find('h2', class_='post-title').string
968
        author = soup.find("span", class_="post-author").find("a").string
969
        date_str = soup.find('span', class_='post-date').string
970
        day = string_to_date(date_str, '%B %d, %Y')
971
        imgs = soup.find('div', class_='comicpane').find_all('img')
972
        assert all(i['alt'] == i['title'] for i in imgs)
973
        title2 = imgs[0]['title']
974
        return {
975
            'day': day.day,
976
            'month': day.month,
977
            'year': day.year,
978
            'img': [i['src'] for i in imgs],
979
            'title': title,
980
            'title2': title2,
981
            'author': author,
982
        }
983
984
@@ 2589-2614 (lines=26) @@
2586
2587
class TheAwkwardYeti(GenericNavigableComic):
2588
    """Class to retrieve The Awkward Yeti comics."""
2589
    # Also on http://www.gocomics.com/the-awkward-yeti
2590
    # Also on http://larstheyeti.tumblr.com
2591
    # Also on https://tapastic.com/series/TheAwkwardYeti
2592
    name = 'yeti'
2593
    long_name = 'The Awkward Yeti'
2594
    url = 'http://theawkwardyeti.com'
2595
    _categories = ('YETI', )
2596
    get_first_comic_link = get_a_navi_navifirst
2597
    get_navi_link = get_link_rel_next
2598
2599
    @classmethod
2600
    def get_comic_info(cls, soup, link):
2601
        """Get information about a particular comics."""
2602
        title = soup.find('h2', class_='post-title').string
2603
        date_str = soup.find("span", class_="post-date").string
2604
        day = string_to_date(date_str, "%B %d, %Y")
2605
        imgs = soup.find("div", id="comic").find_all("img")
2606
        assert all(idx > 0 or i['alt'] == i['title'] for idx, i in enumerate(imgs))
2607
        return {
2608
            'img': [i['src'] for i in imgs],
2609
            'title': title,
2610
            'day': day.day,
2611
            'month': day.month,
2612
            'year': day.year
2613
        }
2614
2615
2616
class PleasantThoughts(GenericNavigableComic):
2617
    """Class to retrieve Pleasant Thoughts comics."""
@@ 2843-2867 (lines=25) @@
2840
2841
class GenericBoumerie(GenericNavigableComic):
2842
    """Generic class to retrieve Boumeries comics in different languages."""
2843
    get_first_comic_link = get_a_navi_navifirst
2844
    get_navi_link = get_link_rel_next
2845
    date_format = NotImplemented
2846
    lang = NotImplemented
2847
2848
    @classmethod
2849
    def get_comic_info(cls, soup, link):
2850
        """Get information about a particular comics."""
2851
        title = soup.find('h2', class_='post-title').string
2852
        short_url = soup.find('link', rel='shortlink')['href']
2853
        author = soup.find("span", class_="post-author").find("a").string
2854
        date_str = soup.find('span', class_='post-date').string
2855
        day = string_to_date(date_str, cls.date_format, cls.lang)
2856
        imgs = soup.find('div', id='comic').find_all('img')
2857
        assert all(i['alt'] == i['title'] for i in imgs)
2858
        return {
2859
            'short_url': short_url,
2860
            'img': [i['src'] for i in imgs],
2861
            'title': title,
2862
            'author': author,
2863
            'month': day.month,
2864
            'year': day.year,
2865
            'day': day.day,
2866
        }
2867
2868
2869
class BoumerieEn(GenericBoumerie):
2870
    """Class to retrieve Boumeries comics in English."""
@@ 2531-2555 (lines=25) @@
2528
2529
class EveryDayBlues(GenericDeletedComic, GenericNavigableComic):
2530
    """Class to retrieve EveryDayBlues Comics."""
2531
    name = "blues"
2532
    long_name = "Every Day Blues"
2533
    url = "http://everydayblues.net"
2534
    get_first_comic_link = get_a_navi_navifirst
2535
    get_navi_link = get_link_rel_next
2536
2537
    @classmethod
2538
    def get_comic_info(cls, soup, link):
2539
        """Get information about a particular comics."""
2540
        title = soup.find("h2", class_="post-title").string
2541
        author = soup.find("span", class_="post-author").find("a").string
2542
        date_str = soup.find("span", class_="post-date").string
2543
        day = string_to_date(date_str, "%d. %B %Y", "de_DE.utf8")
2544
        imgs = soup.find("div", id="comic").find_all("img")
2545
        assert all(i['alt'] == i['title'] == title for i in imgs)
2546
        assert len(imgs) <= 1
2547
        return {
2548
            'img': [i['src'] for i in imgs],
2549
            'title': title,
2550
            'author': author,
2551
            'day': day.day,
2552
            'month': day.month,
2553
            'year': day.year
2554
        }
2555
2556
2557
class BiterComics(GenericNavigableComic):
2558
    """Class to retrieve Biter Comics."""
@@ 1776-1800 (lines=25) @@
1773
1774
class MouseBearComedy(GenericComicNotWorking):  # Website has changed
1775
    """Class to retrieve Mouse Bear Comedy comics."""
1776
    # Also on http://mousebearcomedy.tumblr.com
1777
    name = 'mousebear'
1778
    long_name = 'Mouse Bear Comedy'
1779
    url = 'http://www.mousebearcomedy.com'
1780
    get_first_comic_link = get_a_navi_navifirst
1781
    get_navi_link = get_a_navi_comicnavnext_navinext
1782
1783
    @classmethod
1784
    def get_comic_info(cls, soup, link):
1785
        """Get information about a particular comics."""
1786
        title = soup.find('h2', class_='post-title').string
1787
        author = soup.find("span", class_="post-author").find("a").string
1788
        date_str = soup.find("span", class_="post-date").string
1789
        day = string_to_date(date_str, '%B %d, %Y')
1790
        imgs = soup.find("div", id="comic").find_all("img")
1791
        assert all(i['alt'] == i['title'] == title for i in imgs)
1792
        return {
1793
            'day': day.day,
1794
            'month': day.month,
1795
            'year': day.year,
1796
            'img': [i['src'] for i in imgs],
1797
            'title': title,
1798
            'author': author,
1799
        }
1800
1801
1802
class BigFootJustice(GenericNavigableComic):
1803
    """Class to retrieve Big Foot Justice comics."""
@@ 1184-1207 (lines=24) @@
1181
    url = 'http://english.bouletcorp.com'
1182
1183
1184
class AmazingSuperPowers(GenericNavigableComic):
1185
    """Class to retrieve Amazing Super Powers comics."""
1186
    name = 'asp'
1187
    long_name = 'Amazing Super Powers'
1188
    url = 'http://www.amazingsuperpowers.com'
1189
    get_first_comic_link = get_a_navi_navifirst
1190
    get_navi_link = get_a_navi_navinext
1191
1192
    @classmethod
1193
    def get_comic_info(cls, soup, link):
1194
        """Get information about a particular comics."""
1195
        author = soup.find("span", class_="post-author").find("a").string
1196
        date_str = soup.find('span', class_='post-date').string
1197
        day = string_to_date(date_str, "%B %d, %Y")
1198
        imgs = soup.find('div', id='comic').find_all('img')
1199
        title = ' '.join(i['title'] for i in imgs)
1200
        assert all(i['alt'] == i['title'] for i in imgs)
1201
        return {
1202
            'title': title,
1203
            'author': author,
1204
            'img': [img['src'] for img in imgs],
1205
            'day': day.day,
1206
            'month': day.month,
1207
            'year': day.year
1208
        }
1209
1210
@@ 701-724 (lines=24) @@
698
        }
699
700
701
class OneOneOneOneComic(GenericComicNotWorking, GenericNavigableComic):
702
    """Class to retrieve 1111 Comics."""
703
    # Also on http://comics1111.tumblr.com
704
    # Also on https://tapastic.com/series/1111-Comics
705
    name = '1111'
706
    long_name = '1111 Comics'
707
    url = 'http://www.1111comics.me'
708
    _categories = ('ONEONEONEONE', )
709
    get_first_comic_link = get_div_navfirst_a
710
    get_navi_link = get_link_rel_next
711
712
    @classmethod
713
    def get_comic_info(cls, soup, link):
714
        """Get information about a particular comics."""
715
        title = soup.find('h1', class_='comic-title').find('a').string
716
        date_str = soup.find('header', class_='comic-meta entry-meta').find('a').string
717
        day = string_to_date(date_str, "%B %d, %Y")
718
        imgs = soup.find_all('meta', property='og:image')
719
        return {
720
            'title': title,
721
            'month': day.month,
722
            'year': day.year,
723
            'day': day.day,
724
            'img': [i['content'] for i in imgs],
725
        }
726
727
@@ 929-951 (lines=23) @@
926
        }
927
928
929
class TheGentlemanArmchair(GenericNavigableComic):
930
    """Class to retrieve The Gentleman Armchair comics."""
931
    name = 'gentlemanarmchair'
932
    long_name = 'The Gentleman Armchair'
933
    url = 'http://thegentlemansarmchair.com'
934
    get_first_comic_link = get_a_navi_navifirst
935
    get_navi_link = get_link_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', id='comic').find_all('img')
945
        return {
946
            'img': [i['src'] for i in imgs],
947
            'title': title,
948
            'author': author,
949
            'month': day.month,
950
            'year': day.year,
951
            'day': day.day,
952
        }
953
954
@@ 728-749 (lines=22) @@
725
        }
726
727
728
class AngryAtNothing(GenericDeletedComic, GenericNavigableComic):
729
    """Class to retrieve Angry at Nothing comics."""
730
    # Also on http://tapastic.com/series/Comics-yeah-definitely-comics-
731
    # Also on http://angryatnothing.tumblr.com
732
    name = 'angry'
733
    long_name = 'Angry At Nothing'
734
    url = 'http://www.angryatnothing.net'
735
    get_first_comic_link = get_div_navfirst_a
736
    get_navi_link = get_a_rel_next
737
738
    @classmethod
739
    def get_comic_info(cls, soup, link):
740
        """Get information about a particular comics."""
741
        title = soup.find('h1', class_='comic-title').find('a').string
742
        date_str = soup.find('header', class_='comic-meta entry-meta').find('a').string
743
        day = string_to_date(date_str, "%B %d, %Y")
744
        imgs = soup.find_all('meta', property='og:image')
745
        return {
746
            'title': title,
747
            'month': day.month,
748
            'year': day.year,
749
            'day': day.day,
750
            'img': [i['content'] for i in imgs],
751
        }
752
@@ 2700-2728 (lines=29) @@
2697
2698
class TalesOfAbsurdity(GenericNavigableComic):
2699
    """Class to retrieve Tales Of Absurdity comics."""
2700
    # Also on http://tapastic.com/series/Tales-Of-Absurdity
2701
    # Also on http://talesofabsurdity.tumblr.com
2702
    name = 'absurdity'
2703
    long_name = 'Tales of Absurdity'
2704
    url = 'http://talesofabsurdity.com'
2705
    _categories = ('ABSURDITY', )
2706
    get_first_comic_link = get_a_navi_navifirst
2707
    get_navi_link = get_a_navi_comicnavnext_navinext
2708
2709
    @classmethod
2710
    def get_comic_info(cls, soup, link):
2711
        """Get information about a particular comics."""
2712
        title = soup.find('h2', class_='post-title').string
2713
        author = soup.find("span", class_="post-author").find("a").string
2714
        date_str = soup.find("span", class_="post-date").string
2715
        day = string_to_date(date_str, "%B %d, %Y")
2716
        imgs = soup.find("div", id="comic").find_all("img")
2717
        assert all(i['alt'] == i['title'] for i in imgs)
2718
        alt = imgs[0]['alt'] if imgs else ""
2719
        return {
2720
            'img': [i['src'] for i in imgs],
2721
            'title': title,
2722
            'alt': alt,
2723
            'author': author,
2724
            'day': day.day,
2725
            'month': day.month,
2726
            'year': day.year
2727
        }
2728
2729
2730
class EndlessOrigami(GenericComicNotWorking, GenericNavigableComic):  # Nav not working
2731
    """Class to retrieve Endless Origami Comics."""
@@ 2638-2666 (lines=29) @@
2635
2636
class MisterAndMe(GenericNavigableComic):
2637
    """Class to retrieve Mister & Me Comics."""
2638
    # Also on http://www.gocomics.com/mister-and-me
2639
    # Also on https://tapastic.com/series/Mister-and-Me
2640
    name = 'mister'
2641
    long_name = 'Mister & Me'
2642
    url = 'http://www.mister-and-me.com'
2643
    get_first_comic_link = get_a_comicnavbase_comicnavfirst
2644
    get_navi_link = get_link_rel_next
2645
2646
    @classmethod
2647
    def get_comic_info(cls, soup, link):
2648
        """Get information about a particular comics."""
2649
        title = soup.find('h2', class_='post-title').string
2650
        author = soup.find("span", class_="post-author").find("a").string
2651
        date_str = soup.find("span", class_="post-date").string
2652
        day = string_to_date(date_str, "%B %d, %Y")
2653
        imgs = soup.find("div", id="comic").find_all("img")
2654
        assert all(i['alt'] == i['title'] for i in imgs)
2655
        assert len(imgs) <= 1
2656
        alt = imgs[0]['alt'] if imgs else ""
2657
        return {
2658
            'img': [i['src'] for i in imgs],
2659
            'title': title,
2660
            'alt': alt,
2661
            'author': author,
2662
            'day': day.day,
2663
            'month': day.month,
2664
            'year': day.year
2665
        }
2666
2667
2668
class LastPlaceComics(GenericNavigableComic):
2669
    """Class to retrieve Last Place Comics."""
@@ 2924-2950 (lines=27) @@
2921
2922
class Optipess(GenericNavigableComic):
2923
    """Class to retrieve Optipess comics."""
2924
    name = 'optipess'
2925
    long_name = 'Optipess'
2926
    url = 'http://www.optipess.com'
2927
    get_first_comic_link = get_a_navi_navifirst
2928
    get_navi_link = get_link_rel_next
2929
2930
    @classmethod
2931
    def get_comic_info(cls, soup, link):
2932
        """Get information about a particular comics."""
2933
        title = soup.find('h2', class_='post-title').string
2934
        author = soup.find("span", class_="post-author").find("a").string
2935
        comic = soup.find('div', id='comic')
2936
        imgs = comic.find_all('img') if comic else []
2937
        alt = imgs[0]['title'] if imgs else ""
2938
        assert all(i['alt'] == i['title'] == alt for i in imgs)
2939
        date_str = soup.find('span', class_='post-date').string
2940
        day = string_to_date(date_str, "%B %d, %Y")
2941
        return {
2942
            'title': title,
2943
            'alt': alt,
2944
            'author': author,
2945
            'img': [i['src'] for i in imgs],
2946
            'month': day.month,
2947
            'year': day.year,
2948
            'day': day.day,
2949
        }
2950
2951
2952
class PainTrainComic(GenericNavigableComic):
2953
    """Class to retrieve Pain Train Comics."""
@@ 2559-2585 (lines=27) @@
2556
2557
class BiterComics(GenericNavigableComic):
2558
    """Class to retrieve Biter Comics."""
2559
    name = "biter"
2560
    long_name = "Biter Comics"
2561
    url = "http://www.bitercomics.com"
2562
    get_first_comic_link = get_a_navi_navifirst
2563
    get_navi_link = get_link_rel_next
2564
2565
    @classmethod
2566
    def get_comic_info(cls, soup, link):
2567
        """Get information about a particular comics."""
2568
        title = soup.find("h1", class_="entry-title").string
2569
        author = soup.find("span", class_="author vcard").find("a").string
2570
        date_str = soup.find("span", class_="entry-date").string
2571
        day = string_to_date(date_str, "%B %d, %Y")
2572
        imgs = soup.find("div", id="comic").find_all("img")
2573
        assert all(i['alt'] == i['title'] for i in imgs)
2574
        assert len(imgs) == 1
2575
        alt = imgs[0]['alt']
2576
        return {
2577
            'img': [i['src'] for i in imgs],
2578
            'title': title,
2579
            'alt': alt,
2580
            'author': author,
2581
            'day': day.day,
2582
            'month': day.month,
2583
            'year': day.year
2584
        }
2585
2586
2587
class TheAwkwardYeti(GenericNavigableComic):
2588
    """Class to retrieve The Awkward Yeti comics."""
@@ 2033-2059 (lines=27) @@
2030
2031
class CompletelySeriousComics(GenericNavigableComic):
2032
    """Class to retrieve Completely Serious comics."""
2033
    name = 'completelyserious'
2034
    long_name = 'Completely Serious Comics'
2035
    url = 'http://completelyseriouscomics.com'
2036
    get_first_comic_link = get_a_navi_navifirst
2037
    get_navi_link = get_a_navi_navinext
2038
2039
    @classmethod
2040
    def get_comic_info(cls, soup, link):
2041
        """Get information about a particular comics."""
2042
        title = soup.find('h2', class_='post-title').string
2043
        author = soup.find('span', class_='post-author').contents[1].string
2044
        date_str = soup.find('span', class_='post-date').string
2045
        day = string_to_date(date_str, '%B %d, %Y')
2046
        imgs = soup.find('div', class_='comicpane').find_all('img')
2047
        assert imgs
2048
        alt = imgs[0]['title']
2049
        assert all(i['title'] == i['alt'] == alt for i in imgs)
2050
        return {
2051
            'month': day.month,
2052
            'year': day.year,
2053
            'day': day.day,
2054
            'img': [i['src'] for i in imgs],
2055
            'title': title,
2056
            'alt': alt,
2057
            'author': author,
2058
        }
2059
2060
2061
class PoorlyDrawnLines(GenericListableComic):
2062
    """Class to retrieve Poorly Drawn Lines comics."""
@@ 2732-2757 (lines=26) @@
2729
2730
class EndlessOrigami(GenericComicNotWorking, GenericNavigableComic):  # Nav not working
2731
    """Class to retrieve Endless Origami Comics."""
2732
    name = "origami"
2733
    long_name = "Endless Origami"
2734
    url = "http://endlessorigami.com"
2735
    get_first_comic_link = get_a_navi_navifirst
2736
    get_navi_link = get_link_rel_next
2737
2738
    @classmethod
2739
    def get_comic_info(cls, soup, link):
2740
        """Get information about a particular comics."""
2741
        title = soup.find('h2', class_='post-title').string
2742
        author = soup.find("span", class_="post-author").find("a").string
2743
        date_str = soup.find("span", class_="post-date").string
2744
        day = string_to_date(date_str, "%B %d, %Y")
2745
        imgs = soup.find("div", id="comic").find_all("img")
2746
        assert all(i['alt'] == i['title'] for i in imgs)
2747
        alt = imgs[0]['alt'] if imgs else ""
2748
        return {
2749
            'img': [i['src'] for i in imgs],
2750
            'title': title,
2751
            'alt': alt,
2752
            'author': author,
2753
            'day': day.day,
2754
            'month': day.month,
2755
            'year': day.year
2756
        }
2757
2758
2759
class PlanC(GenericNavigableComic):
2760
    """Class to retrieve Plan C comics."""
@@ 2245-2270 (lines=26) @@
2242
2243
class HappleTea(GenericNavigableComic):
2244
    """Class to retrieve Happle Tea Comics."""
2245
    name = 'happletea'
2246
    long_name = 'Happle Tea'
2247
    url = 'http://www.happletea.com'
2248
    get_first_comic_link = get_a_navi_navifirst
2249
    get_navi_link = get_link_rel_next
2250
2251
    @classmethod
2252
    def get_comic_info(cls, soup, link):
2253
        """Get information about a particular comics."""
2254
        imgs = soup.find('div', id='comic').find_all('img')
2255
        post = soup.find('div', class_='post-content')
2256
        title = post.find('h2', class_='post-title').string
2257
        author = post.find('a', rel='author').string
2258
        date_str = post.find('span', class_='post-date').string
2259
        day = string_to_date(date_str, "%B %d, %Y")
2260
        assert all(i['alt'] == i['title'] for i in imgs)
2261
        return {
2262
            'title': title,
2263
            'img': [i['src'] for i in imgs],
2264
            'alt': ''.join(i['alt'] for i in imgs),
2265
            'month': day.month,
2266
            'year': day.year,
2267
            'day': day.day,
2268
            'author': author,
2269
        }
2270
2271
2272
class RockPaperScissors(GenericNavigableComic):
2273
    """Class to retrieve Rock Paper Scissors comics."""
@@ 1918-1943 (lines=26) @@
1915
1916
class Penmen(GenericNavigableComic):
1917
    """Class to retrieve Penmen comics."""
1918
    name = 'penmen'
1919
    long_name = 'Penmen'
1920
    url = 'http://penmen.com'
1921
    get_navi_link = get_link_rel_next
1922
    get_first_comic_link = simulate_first_link
1923
    first_url = 'http://penmen.com/index.php/2016/09/12/penmen-announces-grin-big-brand-clothing/'
1924
1925
    @classmethod
1926
    def get_comic_info(cls, soup, link):
1927
        """Get information about a particular comics."""
1928
        title = soup.find('title').string
1929
        imgs = soup.find('div', class_='entry-content').find_all('img')
1930
        short_url = soup.find('link', rel='shortlink')['href']
1931
        tags = ' '.join(t.string for t in soup.find_all('a', rel='tag'))
1932
        date_str = soup.find('time')['datetime'][:10]
1933
        day = string_to_date(date_str, "%Y-%m-%d")
1934
        return {
1935
            'title': title,
1936
            'short_url': short_url,
1937
            'img': [i['src'] for i in imgs],
1938
            'tags': tags,
1939
            'month': day.month,
1940
            'year': day.year,
1941
            'day': day.day,
1942
        }
1943
1944
1945
class TheDoghouseDiaries(GenericDeletedComic, GenericNavigableComic):
1946
    """Class to retrieve The Dog House Diaries comics."""
@@ 2401-2425 (lines=25) @@
2398
2399
class LonnieMillsap(GenericNavigableComic):
2400
    """Class to retrieve Lonnie Millsap's comics."""
2401
    name = 'millsap'
2402
    long_name = 'Lonnie Millsap'
2403
    url = 'http://www.lonniemillsap.com'
2404
    get_navi_link = get_link_rel_next
2405
    get_first_comic_link = simulate_first_link
2406
    first_url = 'http://www.lonniemillsap.com/?p=42'
2407
2408
    @classmethod
2409
    def get_comic_info(cls, soup, link):
2410
        """Get information about a particular comics."""
2411
        title = soup.find('h2', class_='post-title').string
2412
        post = soup.find('div', class_='post-content')
2413
        author = post.find("span", class_="post-author").find("a").string
2414
        date_str = post.find("span", class_="post-date").string
2415
        day = string_to_date(date_str, "%B %d, %Y")
2416
        imgs = post.find("div", class_="entry").find_all("img")
2417
        return {
2418
            'title': title,
2419
            'author': author,
2420
            'img': [i['src'] for i in imgs],
2421
            'month': day.month,
2422
            'year': day.year,
2423
            'day': day.day,
2424
        }
2425
2426
2427
class LinsEditions(GenericNavigableComic):
2428
    """Class to retrieve L.I.N.S. Editions comics."""
@@ 2121-2145 (lines=25) @@
2118
2119
class ChuckleADuck(GenericNavigableComic):
2120
    """Class to retrieve Chuckle-A-Duck comics."""
2121
    name = 'chuckleaduck'
2122
    long_name = 'Chuckle-A-duck'
2123
    url = 'http://chuckleaduck.com'
2124
    get_first_comic_link = get_div_navfirst_a
2125
    get_navi_link = get_link_rel_next
2126
2127
    @classmethod
2128
    def get_comic_info(cls, soup, link):
2129
        """Get information about a particular comics."""
2130
        date_str = soup.find('span', class_='post-date').string
2131
        day = string_to_date(remove_st_nd_rd_th_from_date(date_str), "%B %d, %Y")
2132
        author = soup.find('span', class_='post-author').string
2133
        div = soup.find('div', id='comic')
2134
        imgs = div.find_all('img') if div else []
2135
        title = imgs[0]['title'] if imgs else ""
2136
        assert all(i['title'] == i['alt'] == title for i in imgs)
2137
        return {
2138
            'month': day.month,
2139
            'year': day.year,
2140
            'day': day.day,
2141
            'img': [i['src'] for i in imgs],
2142
            'title': title,
2143
            'author': author,
2144
        }
2145
2146
2147
class DepressedAlien(GenericNavigableComic):
2148
    """Class to retrieve Depressed Alien Comics."""
@@ 3242-3265 (lines=24) @@
3239
    get_url_from_link = join_cls_url_to_href
3240
    get_first_comic_link = simulate_first_link
3241
    first_url = 'http://www.earthexplodes.com/comics/000/'
3242
3243
    @classmethod
3244
    def get_navi_link(cls, last_soup, next_):
3245
        """Get link to next or previous comic."""
3246
        return last_soup.find('a', id='next' if next_ else 'prev')
3247
3248
    @classmethod
3249
    def get_comic_info(cls, soup, link):
3250
        """Get information about a particular comics."""
3251
        title = soup.find('title').string
3252
        imgs = soup.find('div', id='image').find_all('img')
3253
        alt = imgs[0].get('title', '')
3254
        return {
3255
            'img': [urljoin_wrapper(cls.url, i['src']) for i in imgs],
3256
            'title': title,
3257
            'alt': alt,
3258
        }
3259
3260
3261
class PomComics(GenericNavigableComic):
3262
    """Class to retrieve PomComics."""
3263
    name = 'pom'
3264
    long_name = 'Pom Comics / Piece of Me'
3265
    url = 'http://www.pomcomic.com'
3266
    get_url_from_link = join_cls_url_to_href
3267
3268
    @classmethod
@@ 675-697 (lines=23) @@
672
        }
673
674
675
class PenelopeBagieu(GenericNavigableComic):
676
    """Class to retrieve comics from Penelope Bagieu's blog."""
677
    name = 'bagieu'
678
    long_name = 'Ma vie est tout a fait fascinante (Bagieu)'
679
    url = 'http://www.penelope-jolicoeur.com'
680
    _categories = ('FRANCAIS', )
681
    get_navi_link = get_link_rel_next
682
    get_first_comic_link = simulate_first_link
683
    first_url = 'http://www.penelope-jolicoeur.com/2007/02/ma-vie-mon-oeuv.html'
684
685
    @classmethod
686
    def get_comic_info(cls, soup, link):
687
        """Get information about a particular comics."""
688
        date_str = soup.find('h2', class_='date-header').string
689
        day = string_to_date(date_str, "%A %d %B %Y", "fr_FR.utf8")
690
        imgs = soup.find('div', class_='entry-body').find_all('img')
691
        title = soup.find('h3', class_='entry-header').string
692
        return {
693
            'title': title,
694
            'img': [i['src'] for i in imgs],
695
            'month': day.month,
696
            'year': day.year,
697
            'day': day.day,
698
        }
699
700
@@ 2761-2781 (lines=21) @@
2758
2759
class PlanC(GenericNavigableComic):
2760
    """Class to retrieve Plan C comics."""
2761
    name = 'planc'
2762
    long_name = 'Plan C'
2763
    url = 'http://www.plancomic.com'
2764
    get_first_comic_link = get_a_navi_navifirst
2765
    get_navi_link = get_a_navi_comicnavnext_navinext
2766
2767
    @classmethod
2768
    def get_comic_info(cls, soup, link):
2769
        """Get information about a particular comics."""
2770
        title = soup.find('h2', class_='post-title').string
2771
        date_str = soup.find("span", class_="post-date").string
2772
        day = string_to_date(date_str, "%B %d, %Y")
2773
        imgs = soup.find('div', id='comic').find_all('img')
2774
        return {
2775
            'title': title,
2776
            'img': [i['src'] for i in imgs],
2777
            'month': day.month,
2778
            'year': day.year,
2779
            'day': day.day,
2780
        }
2781
2782
2783
class BuniComic(GenericNavigableComic):
2784
    """Class to retrieve Buni Comics."""