1010from datetime import datetime
1111from configparser import ConfigParser
1212
13+ import yaml
1314from inoreader import InoreaderClient
15+ from inoreader .filter import Filter
1416
1517
1618APPID_ENV_NAME = 'INOREADER_APP_ID'
@@ -162,6 +164,73 @@ def fetch_unread(folder, tags, outfile, out_format):
162164 fout .close ()
163165
164166
167+ def add_filter_parser (subparsers ):
168+ parser = subparsers .add_parser ('filter' , help = 'Select articles and do something' )
169+ parser .add_argument ("-f" , "--folder" , required = True , help = 'Folder which articles belong to' )
170+ parser .add_argument ("-r" , "--rules" , required = True , help = 'YAML file with your rules' )
171+ parser .add_argument ("-a" , "--action" , default = 'read' ,
172+ choices = ['read' , 'like' , 'tag' , 'broadcast' , 'star' ],
173+ help = 'Action you want to perform, default: read' )
174+ parser .add_argument ("-t" , "--tags" ,
175+ help = "Tag(s) to be used when action is 'tag', seprate with comma" )
176+
177+
178+ def apply_action (articles , client , action , tags ):
179+ if action == 'tag' :
180+ for tag in tags .split (',' ):
181+ client .add_tag (articles , tag )
182+
183+ for article in articles :
184+ print ("Add tags [{}] on article: {}" .format (tags , article .title ))
185+ elif action == 'read' :
186+ client .mark_as_read (articles )
187+ for article in articles :
188+ print ("Mark article as read: {}" .format (article .title ))
189+ elif action == 'like' :
190+ client .mark_as_liked (articles )
191+ for article in articles :
192+ print ("Mark article as liked: {}" .format (article .title ))
193+ elif action == 'broadcast' :
194+ client .broadcast (articles )
195+ for article in articles :
196+ print ("Boradcast article: {}" .format (article .title ))
197+ elif action == 'star' :
198+ client .mark_as_starred (articles )
199+ for article in articles :
200+ print ("Starred article: {}" .format (article .title ))
201+
202+
203+ def filter_articles (folder , rules_file , action , tags ):
204+ client = get_client ()
205+ filters = []
206+ for rule in yaml .load (open (rules_file )):
207+ filters .append ({
208+ 'field' : rule .get ('field' , 'title' ),
209+ 'filter' : Filter .from_config (rule ),
210+ })
211+
212+ matched_articles = []
213+ for idx , article in enumerate (client .fetch_unread (folder = folder )):
214+ matched = False
215+ for article_filter in filters :
216+ if article_filter ['field' ] in ('title' , 'title_or_content' ) and \
217+ article_filter ['filter' ].validate (article .title ):
218+ matched = True
219+ break
220+ if article_filter ['field' ] in ('content' , 'title_or_content' ) and \
221+ article_filter ['filter' ].validate (article .text ):
222+ matched = True
223+ break
224+ if matched :
225+ matched_articles .append (article )
226+ if len (matched_articles ) == 10 :
227+ apply_action (matched_articles , client , action , tags )
228+ matched_articles = []
229+
230+ if matched_articles :
231+ apply_action (matched_articles , client , action , tags )
232+
233+
165234def main ():
166235 parser = CmdParser (
167236 usage = "inoreader [-h] <command> ..." ,
@@ -174,6 +243,7 @@ def main():
174243 add_folders_list_parser (subparsers )
175244 add_tags_list_parser (subparsers )
176245 add_unread_fetch_parser (subparsers )
246+ add_filter_parser (subparsers )
177247
178248 args = parser .parse_args ()
179249 if args .command == 'login' :
@@ -184,6 +254,12 @@ def main():
184254 list_tags ()
185255 elif args .command == 'fetch-unread' :
186256 fetch_unread (args .folder , args .tags , args .outfile , args .out_format )
257+ elif args .command == 'filter' :
258+ if args .action == 'tag' and not args .tags :
259+ print ("Need at least one tag when action is 'tag'!" )
260+ sys .exit (1 )
261+
262+ filter_articles (args .folder , args .rules , args .action , args .tags )
187263
188264
189265if __name__ == '__main__' :
0 commit comments