Skip to content

Commit a6fbea0

Browse files
authored
Merge pull request #5 from schemen/devel
Merge Devel into master!
2 parents 460f1b4 + 1d5fd0e commit a6fbea0

12 files changed

+904
-284
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ comic/*
77
kindlegen.exe
88
.idea
99
venv
10-
main.db
10+
main.db
11+
log/*

README.md

+63-16
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,29 @@ As a concept, M2em has different workers that run in a loop. All Chapter/user da
4646
* Converter - Converting images into ebooks
4747
* Sender - Compiling & Sending Emails to users and marking them as SENT
4848

49-
With the sourceparser you can add support of a Webhost.
49+
50+
### The Loop Run & Daemon Loop Run
51+
If you start m2em in loop mode (with or without --daemon) it will only consider any action with elements that that are
52+
younger than 24h hours.
53+
54+
The use of that is having it running on the server 24/7, waiting for updates from the feeds and ONLY handling said updates.
55+
56+
### Direct action
57+
You can start a part of the loop without the restriction of 24h. Use the -a (--action) command with either element you wish to start.
58+
59+
Example: if you wish to download all chapters you have saved in your database, you start the download action.
60+
```
61+
./m2em.py --action downloader
62+
```
63+
### Chapter action
64+
You can directly apply an action to one chapter with the options --download, --convert or --send. You need to pass
65+
the ID of said chapter, you can find that out with "-Lc" or "-lc".
66+
You can pass multiple IDs.
67+
Example:
68+
```
69+
./m2em.py --download 100 #Downloads chapter with ID 100
70+
```
71+
5072

5173
## Supported Websites
5274
* Mangastream
@@ -56,27 +78,42 @@ With the sourceparser you can add support of a Webhost.
5678

5779
### Help output:
5880
```
59-
usage: m2em.py [-h] [-r RSS_FEED] [-u] [-l] [-L] [--list-feeds] [--list-users]
60-
[-cd] [-s SWITCH_SEND] [-S SWITCH_CHAPTER] [-dc DELETE_CHAPTER]
61-
[-du DELETE_USER] [-df DELETE_FEED] [--daemon] [-d]
81+
usage: m2em.py [-h] [-af ADD_FEED] [-au] [-lc] [-Lc] [-lf] [-lu] [-cd] [-s]
82+
[--send [SEND [SEND ...]]] [--convert [CONVERT [CONVERT ...]]]
83+
[--download [DOWNLOAD [DOWNLOAD ...]]] [-a ACTION]
84+
[-ss SWITCH_SEND] [-sc SWITCH_CHAPTER] [-dc DELETE_CHAPTER]
85+
[-du DELETE_USER] [-df DELETE_FEED] [--daemon] [-d] [-v]
6286
6387
Manga to eManga - m2em
6488
6589
optional arguments:
6690
-h, --help show this help message and exit
67-
-r RSS_FEED, --rss-feed RSS_FEED
91+
-af ADD_FEED, --add-feed ADD_FEED
6892
Add RSS Feed of Manga. Only Mangastream & MangaFox are
6993
supported
70-
-u, --add-user Adds new user
71-
-l, --list-chapters Lists the last 10 Chapters
72-
-L, --list-chapters-all
94+
-au, --add-user Adds new user
95+
-lc, --list-chapters Lists the last 10 Chapters
96+
-Lc, --list-chapters-all
7397
Lists all Chapters
74-
--list-feeds Lists all feeds
75-
--list-users Lists all Users
98+
-lf, --list-feeds Lists all feeds
99+
-lu, --list-users Lists all Users
76100
-cd, --create-db Creates DB. Uses Configfile for Naming
77-
-s SWITCH_SEND, --switch-send SWITCH_SEND
101+
-s, --start Starts one loop
102+
--send [SEND [SEND ...]]
103+
Sends Chapter directly by chapter ID. Multiple IDs can
104+
be given
105+
--convert [CONVERT [CONVERT ...]]
106+
Converts Chapter directly by chapter ID. Multiple IDs
107+
can be given
108+
--download [DOWNLOAD [DOWNLOAD ...]]
109+
Downloads Chapter directly by chapter ID. Multiple IDs
110+
can be given
111+
-a ACTION, --action ACTION
112+
Start action. Options are: rssparser (collecting feed
113+
data), downloader, converter or sender
114+
-ss SWITCH_SEND, --switch-send SWITCH_SEND
78115
Pass ID of User. Switches said user Send eBook status
79-
-S SWITCH_CHAPTER, --switch-chapter SWITCH_CHAPTER
116+
-sc SWITCH_CHAPTER, --switch-chapter SWITCH_CHAPTER
80117
Pass ID of Chapter. Switches said Chapter Sent status
81118
-dc DELETE_CHAPTER, --delete-chapter DELETE_CHAPTER
82119
Pass ID of Chapter. Deletes said Chapter
@@ -86,13 +123,15 @@ optional arguments:
86123
Pass ID of Feed. Deletes said Feed
87124
--daemon Run as daemon
88125
-d, --debug Debug Mode
126+
-v, --version show program's version number and exit
127+
89128
```
90129

91130
## Initial Data
92131
To have a working environment you need to add some initial data and create the database
93132
```x-sh
94133
./m2em.py --create-db # Create a DB
95-
./m2em.py --rss-feed <URL> # Add an RSS Feed you want to pull
134+
./m2em.py --add-feed <URL> # Add an RSS Feed you want to pull
96135
# Please note that you should set the sending AFTER a complete run for now
97136
./m2em.py --add-user # Add a user
98137
@@ -127,10 +166,19 @@ ServerStartSSL = True
127166

128167
To start a single run through the workers, you can simply execute the main program:
129168
```
130-
./m2em.py
169+
./m2em.py -s
170+
```
171+
172+
If you wish to run the program as a daemon, start it with the option "--daemon" as well. It will re-run at the config "Sleep" in second.
173+
```
174+
./m2em.py -s --daemon
175+
```
176+
177+
If you wish to disable/enable sending status of a user, use the -ss command
178+
```
179+
./m2em.py -ss <USERID>
131180
```
132181

133-
If you wish to run the program as a daemon, start it with the option "--daemon". It will re-run at the config "Sleep" in second.
134182

135183

136184
### A complete run with nothing happening:
@@ -152,7 +200,6 @@ Finished sending ebooks!
152200
Everything else should be self-explanatory with the "-h" option.
153201

154202
## Known Issues
155-
* There is a huge data load in the beginning. It is recommended to only activate sending of Emails after one complete run
156203
* MangaFox has issues with SSL Verification on some systems. For now, Simply add the http feed.
157204

158205
Please Open an issue if you find anything!

bin/_version.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__version__ = "v0.3.0"

bin/m2emConverter.py

+45-32
Original file line numberDiff line numberDiff line change
@@ -5,70 +5,83 @@
55
import bin.m2emHelper as helper
66

77

8-
def RecursiveConverter(config):
8+
class Converter:
99

10-
# Load configs required here
11-
database = config["Database"]
12-
saveloc = config["SaveLocation"]
13-
ebformat = config["EbookFormat"]
14-
ebprofile = config["EbookProfile"]
10+
def __init__(self):
11+
self.saveloc = None
12+
self.ebformat = None
13+
self.ebprofile = None
14+
self.mangatitle = None
15+
self.manganame = None
16+
self.imagefolder = None
17+
self.eblocation = None
18+
self.cbzlocation = None
19+
self.chapterdate = None
1520

16-
# Load Chapters from Database
17-
chapters = helper.getChapters(database)
1821

1922

20-
# Start conversion loop!
21-
for chapter in chapters:
23+
def data_collector(self, config, chapter):
24+
25+
# Load configs required here
26+
self.saveloc = config["SaveLocation"]
27+
self.ebformat = config["EbookFormat"]
28+
self.ebprofile = config["EbookProfile"]
29+
2230

2331
# get relevant data of this Manga
24-
mangatitle = chapter[2]
25-
manganame = chapter[11]
32+
self.mangatitle = chapter[2]
33+
self.manganame = chapter[11]
34+
self.chapterdate = chapter[3]
35+
36+
# check if mangatitle or manganame contains ":" characters that OS can't handle as folders
37+
self.mangatitle = helper.sanetizeName(self.mangatitle)
38+
self.manganame = helper.sanetizeName(self.manganame)
39+
2640

27-
# check if mangatitle contains ":" characters that OS can't handle as folders
28-
mangatitle = helper.sanetizeName(mangatitle)
41+
# create folder variables
42+
self.imagefolder = str(self.saveloc + self.manganame + "/"+ self.mangatitle + "/images/")
43+
self.eblocation = str(self.saveloc + self.manganame + "/"+ self.mangatitle + "/" + self.mangatitle + "." + self.ebformat.lower())
44+
self.cbzlocation = str(self.saveloc + self.manganame + "/"+ self.mangatitle + "/" + self.mangatitle + ".cbz")
2945

30-
# check if manganame contains ":" characters that OS can't handle as folders
31-
manganame = helper.sanetizeName(manganame)
3246

33-
imagefolder = str(saveloc + manganame + "/"+ mangatitle + "/images/")
34-
eblocation = str(saveloc + manganame + "/"+ mangatitle + "/" + mangatitle + "." + ebformat.lower())
35-
cbzlocation = str(saveloc + manganame + "/"+ mangatitle + "/" + mangatitle + ".cbz")
3647

3748

49+
def cbz_creator(self):
50+
3851
# Create CBZ to make creation easier
39-
if os.path.exists(cbzlocation):
40-
logging.debug("Manga %s converted to CBZ already!" % mangatitle)
52+
if os.path.exists(self.cbzlocation):
53+
logging.debug("Manga %s converted to CBZ already!" % self.mangatitle)
4154
else:
42-
logging.info("Starting conversion to CBZ of %s..." % mangatitle)
55+
logging.info("Starting conversion to CBZ of %s..." % self.mangatitle)
4356

4457

4558
logging.debug("Opening CBZ archive...")
4659
try:
47-
zf = zipfile.ZipFile(cbzlocation, "w")
60+
zf = zipfile.ZipFile(self.cbzlocation, "w")
4861
except Exception as e:
4962
logging.warning("Failed opening archive! %s" % e)
5063

5164

5265

5366
logging.debug("Writing Images into CBZ")
54-
for img in sorted(os.listdir(imagefolder)):
55-
image = imagefolder + img
67+
for img in sorted(os.listdir(self.imagefolder)):
68+
image = self.imagefolder + img
5669
logging.debug("Writing %s" % image)
5770
zf.write(image,img)
5871

5972
zf.close()
6073

6174

75+
76+
def eb_creator(self):
77+
6278
# Start conversion to Ebook format!
63-
if os.path.exists(eblocation):
64-
logging.debug("Manga %s converted to Ebook already!" % mangatitle)
79+
if os.path.exists(self.eblocation):
80+
logging.debug("Manga %s converted to Ebook already!" % self.mangatitle)
6581
else:
66-
logging.info("Starting conversion to Ebook of %s..." % mangatitle)
82+
logging.info("Starting conversion to Ebook of %s..." % self.mangatitle)
6783

6884
try:
69-
subprocess.call(["kcc-c2e", "-p", ebprofile, "-f", ebformat, "-m", "-q", "-r", "2", "-u", "-s", cbzlocation])
85+
subprocess.call(["kcc-c2e", "-p", self.ebprofile, "-f", self.ebformat, "-m", "-q", "-r", "2", "-u", "-s", self.cbzlocation])
7086
except Exception as e:
7187
logging.debug("Failed to convert epub %s" % e)
72-
73-
def ChapterConverter(imagelocation, config):
74-
pass

bin/m2emConverterHandler.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import logging
2+
import os
3+
import bin.m2emHelper as helper
4+
from bin.m2emConverter import Converter
5+
6+
7+
def ConverterHandler(config, args):
8+
9+
# Load configs required here
10+
database = config["Database"]
11+
12+
# Load Chapters!
13+
chapters = helper.getChapters(database)
14+
15+
16+
# Start conversion loop!
17+
for chapter in chapters:
18+
19+
20+
21+
# Verify if chapter has been downloaded already
22+
if not helper.verifyDownload(config, chapter):
23+
logging.debug("Manga %s has not been downloaded!" % chapter[2])
24+
else:
25+
26+
27+
# Spawn an Converter Object & get basic data from database & config
28+
current_conversation = Converter()
29+
current_conversation.data_collector(config,chapter)
30+
31+
# Check if Download loop & Download task is selected
32+
if not args.start:
33+
current_conversation.cbz_creator()
34+
current_conversation.eb_creator()
35+
else:
36+
37+
# Only start run if chapter is younger than 24h
38+
if helper.checkTime(current_conversation.chapterdate):
39+
current_conversation.cbz_creator()
40+
current_conversation.eb_creator()
41+
else:
42+
logging.debug("%s is older than 24h, will not be processed by daemon." % current_conversation.mangatitle)
43+
44+
45+
46+
47+
def directConverter(config, chapterids=[]):
48+
49+
logging.debug("Following Chapters are directly converted:")
50+
logging.debug(chapterids)
51+
52+
# Load configs required here
53+
database = config["Database"]
54+
55+
56+
chapters = helper.getChaptersFromID(database, chapterids)
57+
58+
59+
if not chapters:
60+
logging.error("No Chapters found with said ID!")
61+
else:
62+
# Start conversion loop!
63+
for chapter in chapters:
64+
65+
# Verify if chapter has been downloaded already
66+
if not helper.verifyDownload(config, chapter):
67+
logging.info("Manga %s has not been downloaded!" % chapter[2])
68+
else:
69+
70+
71+
# Spawn an Converter Object & get basic data from database & config
72+
current_conversation = Converter()
73+
current_conversation.data_collector(config,chapter)
74+
75+
if os.path.exists(current_conversation.cbzlocation):
76+
logging.info("Manga %s converted to CBZ already!" % current_conversation.mangatitle)
77+
else:
78+
logging.info("Starting conversion to CBZ of %s..." % current_conversation.mangatitle)
79+
current_conversation.cbz_creator()
80+
81+
# Start conversion to Ebook format!
82+
if os.path.exists(current_conversation.eblocation):
83+
logging.info("Manga %s converted to Ebook already!" % current_conversation.mangatitle)
84+
else:
85+
logging.info("Starting conversion to Ebook of %s..." % current_conversation.mangatitle)
86+
current_conversation.eb_creator()

0 commit comments

Comments
 (0)