Working
This commit is contained in:
		
							parent
							
								
									904f86c754
								
							
						
					
					
						commit
						e3bf0462ec
					
				| @ -4,4 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| Simple project to determine health of the devrant platform. | Simple project to determine health of the devrant platform. | ||||||
| 
 | 
 | ||||||
|  | ## Credits | ||||||
|  | Thanks to Rohan Burke (coolq). The creator of the dr api wrapper this project uses. Since it isn't made like a package, i had to copy his source files to my source folder. His library: https://github.com/coolq1000/devrant-python-api/ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								drstats.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								drstats.db
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -16,12 +16,14 @@ python_requires = >=3.7 | |||||||
| install_requires = | install_requires = | ||||||
|     aiohttp>=3.10.10 |     aiohttp>=3.10.10 | ||||||
|     dataset>=1.6.2 |     dataset>=1.6.2 | ||||||
|     pirant>=0.1.4.dev1 |     matplotlib>=3.9.2 | ||||||
|     git+https://github.com/aayush26/pirant |  | ||||||
|      |      | ||||||
| [options.packages.find] | [options.packages.find] | ||||||
| where = src | where = src | ||||||
| 
 | 
 | ||||||
| [options.entry_points] | [options.entry_points] | ||||||
| console_scripts = | console_scripts = | ||||||
|     dr.rant_stats = drstats.statistics:rant_stats |     dr.sync = drstats.sync:sync | ||||||
|  |     dr.rant_stats_per_day = drstats.statistics:rant_stats_per_day | ||||||
|  |     dr.rant_stats_per_weekday = drstats.statistics:rant_stats_per_weekday | ||||||
|  |     dr.rant_stats_per_hour = drstats.statistics:rant_stats_per_hour | ||||||
| @ -9,6 +9,7 @@ Requires-Python: >=3.7 | |||||||
| Description-Content-Type: text/markdown | Description-Content-Type: text/markdown | ||||||
| Requires-Dist: aiohttp>=3.10.10 | Requires-Dist: aiohttp>=3.10.10 | ||||||
| Requires-Dist: dataset>=1.6.2 | Requires-Dist: dataset>=1.6.2 | ||||||
|  | Requires-Dist: matplotlib>=3.9.2 | ||||||
| 
 | 
 | ||||||
| # dRStats | # dRStats | ||||||
| 
 | 
 | ||||||
| @ -16,4 +17,7 @@ Requires-Dist: dataset>=1.6.2 | |||||||
| 
 | 
 | ||||||
| Simple project to determine health of the devrant platform. | Simple project to determine health of the devrant platform. | ||||||
| 
 | 
 | ||||||
|  | ## Credits | ||||||
|  | Thanks to Rohan Burke (coolq). The creator of the dr api wrapper this project uses. Since it isn't made like a package, i had to copy his source files to my source folder. His library: https://github.com/coolq1000/devrant-python-api/ | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,7 +3,10 @@ pyproject.toml | |||||||
| setup.cfg | setup.cfg | ||||||
| src/drstats/__init__.py | src/drstats/__init__.py | ||||||
| src/drstats/__main__.py | src/drstats/__main__.py | ||||||
|  | src/drstats/db.py | ||||||
|  | src/drstats/devrant.py | ||||||
| src/drstats/statistics.py | src/drstats/statistics.py | ||||||
|  | src/drstats/sync.py | ||||||
| src/drstats.egg-info/PKG-INFO | src/drstats.egg-info/PKG-INFO | ||||||
| src/drstats.egg-info/SOURCES.txt | src/drstats.egg-info/SOURCES.txt | ||||||
| src/drstats.egg-info/dependency_links.txt | src/drstats.egg-info/dependency_links.txt | ||||||
|  | |||||||
| @ -1,2 +1,5 @@ | |||||||
| [console_scripts] | [console_scripts] | ||||||
| dr.rant_stats = drstats.statistics:rant_stats | dr.rant_stats_per_day = drstats.statistics:rant_stats_per_day | ||||||
|  | dr.rant_stats_per_hour = drstats.statistics:rant_stats_per_hour | ||||||
|  | dr.rant_stats_per_weekday = drstats.statistics:rant_stats_per_weekday | ||||||
|  | dr.sync = drstats.sync:sync | ||||||
|  | |||||||
| @ -1,2 +1,3 @@ | |||||||
| aiohttp>=3.10.10 | aiohttp>=3.10.10 | ||||||
| dataset>=1.6.2 | dataset>=1.6.2 | ||||||
|  | matplotlib>=3.9.2 | ||||||
|  | |||||||
							
								
								
									
										0
									
								
								src/drstats/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/drstats/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								src/drstats/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/drstats/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/drstats/__pycache__/__init__.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/drstats/__pycache__/__init__.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/drstats/__pycache__/db.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/drstats/__pycache__/db.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/drstats/__pycache__/devrant.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/drstats/__pycache__/devrant.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/drstats/__pycache__/statistics.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/drstats/__pycache__/statistics.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/drstats/__pycache__/sync.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/drstats/__pycache__/sync.cpython-312.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										47
									
								
								src/drstats/db.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/drstats/db.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | db_path = "./drstats.db" | ||||||
|  | import dataset  | ||||||
|  | 
 | ||||||
|  | def get_db(): | ||||||
|  |     db = dataset.connect(f"sqlite:///{db_path}") | ||||||
|  |     db.query("drop view if exists rant_stats_per_day") | ||||||
|  |     db.query(""" | ||||||
|  | CREATE VIEW rant_stats_per_day AS SELECT  | ||||||
|  |     count(0) AS count,  | ||||||
|  |     DATE(created) AS created_date,  | ||||||
|  |     CASE strftime('%w', DATE(created)) | ||||||
|  |         WHEN '0' THEN 'Sunday' | ||||||
|  |         WHEN '1' THEN 'Monday' | ||||||
|  |         WHEN '2' THEN 'Tuesday' | ||||||
|  |         WHEN '3' THEN 'Wednesday' | ||||||
|  |         WHEN '4' THEN 'Thursday' | ||||||
|  |         WHEN '5' THEN 'Friday' | ||||||
|  |         WHEN '6' THEN 'Saturday' | ||||||
|  |     END AS weekday | ||||||
|  | FROM rants  | ||||||
|  | GROUP BY created_date  | ||||||
|  | ORDER BY created_date;              | ||||||
|  | """) | ||||||
|  |     db.query("DROP VIEW IF EXISTS rant_stats_per_weekday") | ||||||
|  |     db.query(""" | ||||||
|  | CREATE VIEW rant_stats_per_weekday AS SELECT  | ||||||
|  |     count(0) AS count,  | ||||||
|  |     DATE(created) AS created_date,  | ||||||
|  |     CASE strftime('%w', DATE(created)) | ||||||
|  |         WHEN '0' THEN 'Sunday' | ||||||
|  |         WHEN '1' THEN 'Monday' | ||||||
|  |         WHEN '2' THEN 'Tuesday' | ||||||
|  |         WHEN '3' THEN 'Wednesday' | ||||||
|  |         WHEN '4' THEN 'Thursday' | ||||||
|  |         WHEN '5' THEN 'Friday' | ||||||
|  |         WHEN '6' THEN 'Saturday' | ||||||
|  |     END AS weekday | ||||||
|  | FROM rants  | ||||||
|  | GROUP BY weekday  | ||||||
|  | ORDER BY created_date;              | ||||||
|  | """) | ||||||
|  |     db.query("drop view if exists rant_stats_per_hour") | ||||||
|  |     db.query("create view rant_stats_per_hour as select count(0) as count, strftime('%H', created) AS hour from rants GROUP BY hour order by hour") | ||||||
|  |     #db.query("drop view if exists rant_stats_per_weekday") | ||||||
|  |     #db.query("create view rant_stats_per_weekday as select count(0) as count, strftime('%w',created) as weekday_int, strftime('%A',created) as weekday from rants group by weekday_int order by weekday_int;") | ||||||
|  | 
 | ||||||
|  |     return db | ||||||
							
								
								
									
										93
									
								
								src/drstats/devrant.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/drstats/devrant.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | |||||||
|  | """ | ||||||
|  | 	Devrant.io API. Written by Rohan Burke (coolq). | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | import requests, json | ||||||
|  | 
 | ||||||
|  | class Devrant: | ||||||
|  | 
 | ||||||
|  | 	API = 'https://www.devrant.io/api/' | ||||||
|  | 
 | ||||||
|  | 	""" | ||||||
|  | 		get_profile(id): | ||||||
|  | 			Return JSON object with all information about that user. | ||||||
|  | 	""" | ||||||
|  | 	def get_profile(self, id_): | ||||||
|  | 		url = self.API + 'users/' + str(id_) | ||||||
|  | 		params = { | ||||||
|  | 			'app': 3, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		r = requests.get(url, params) | ||||||
|  | 		obj = json.loads(r.text) | ||||||
|  | 		return obj | ||||||
|  | 
 | ||||||
|  | 	""" | ||||||
|  | 		get_search(term): | ||||||
|  | 			Return JSON object containing all results of that search. Index ['rants'] for rants. | ||||||
|  | 	""" | ||||||
|  | 	def get_search(self, term): | ||||||
|  | 		url = self.API + 'devrant/search' | ||||||
|  | 		params = { | ||||||
|  | 			'app': 3, | ||||||
|  | 			'term': term | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		r = requests.get(url, params) | ||||||
|  | 		obj = json.loads(r.text) | ||||||
|  | 		return obj | ||||||
|  | 
 | ||||||
|  | 	""" | ||||||
|  | 		get_rant(sort, index): | ||||||
|  | 			Return JSON object of that rant. | ||||||
|  | 	""" | ||||||
|  | 	def get_rant(self, sort, index): | ||||||
|  | 		rants = self.get_rants(sort, 1, index)['rants'] | ||||||
|  | 		if rants: | ||||||
|  | 			return rants[0] | ||||||
|  | 
 | ||||||
|  | 	""" | ||||||
|  | 		get_rants(sort, limit, skip): | ||||||
|  | 			Return JSON object with range skip-limit. Max limit is 50, increase the skip to get rants further down. | ||||||
|  | 	""" | ||||||
|  | 	def get_rants(self, sort, limit, skip): | ||||||
|  | 		url = self.API + 'devrant/rants' | ||||||
|  | 		params = { | ||||||
|  | 			'app': 3, | ||||||
|  | 			'sort': sort, | ||||||
|  | 			'limit': limit, | ||||||
|  | 			'skip': skip | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		r = requests.get(url, params) | ||||||
|  | 		obj = json.loads(r.text) | ||||||
|  | 		return obj | ||||||
|  | 
 | ||||||
|  | 	""" | ||||||
|  | 		get_user_id(name): | ||||||
|  | 			Return JSON with containing the id for that user, E.g. if `coolq` is inputted, it shall return `{'success': True, 'user_id': 703149}`. | ||||||
|  | 	""" | ||||||
|  | 	def get_user_id(self, name): | ||||||
|  | 		url = self.API + 'get-user-id' | ||||||
|  | 		params = { | ||||||
|  | 			'app': 3, | ||||||
|  | 			'username': name | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		r = requests.get(url, params) | ||||||
|  | 		obj = json.loads(r.text) | ||||||
|  | 		return obj | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  | 	# Simple demo, runs through rants sorted by most recent. | ||||||
|  | 	dr = Devrant() | ||||||
|  | 	i = 0 | ||||||
|  | 	while True: | ||||||
|  | 		result = dr.get_rant('recent', i) | ||||||
|  | 		print('\n'*50) | ||||||
|  | 		name = result['user_username'] | ||||||
|  | 		tags = ', '.join(result['tags']) | ||||||
|  | 		print('-' + name + '-'*(50 - (len(name) + 1))) | ||||||
|  | 		print(result['text']) | ||||||
|  | 		print('-' + tags + '-'*(50 - (len(tags) + 1))) | ||||||
|  | 		i += 1 | ||||||
							
								
								
									
										73
									
								
								src/drstats/statistics.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/drstats/statistics.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | from drstats.db import get_db  | ||||||
|  | from drstats import sync  | ||||||
|  | import asyncio | ||||||
|  | import matplotlib | ||||||
|  | import matplotlib.pyplot as plt | ||||||
|  | 
 | ||||||
|  | def get_date_range(): | ||||||
|  |     db = get_db() | ||||||
|  |     for record in db.query("SELECT min(date(created)) as start_date, max(date(created)) as end_date FROM rants"): | ||||||
|  |         return record['start_date'], record['end_date'] | ||||||
|  |      | ||||||
|  | def get_date_range_str(): | ||||||
|  |     start_date, end_date = get_date_range() | ||||||
|  |     return f"from {start_date} to {end_date}" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def rant_stats_per_day(): | ||||||
|  |     db = get_db() | ||||||
|  |     x = [] | ||||||
|  |     y = [] | ||||||
|  |     matplotlib.use('TkAgg') | ||||||
|  |     for record in db.query("SELECT * FROM rant_stats_per_day"): | ||||||
|  |         print(record) | ||||||
|  |         y.append(record['count']) | ||||||
|  |         x.append(record['created_date'].replace('2014-',"") + " " + str(record['weekday'])) | ||||||
|  | 
 | ||||||
|  |     plt.plot(x, y, label=get_date_range_str(), color='blue') | ||||||
|  |     plt.xticks(rotation=20) | ||||||
|  |     plt.xlabel('Date') | ||||||
|  |     plt.ylabel('Rant count') | ||||||
|  |     plt.title('Rants per day') | ||||||
|  |     plt.legend() | ||||||
|  |     plt.savefig(f'export/rants_per_day_{get_date_range_str()}.png') | ||||||
|  |     plt.show() | ||||||
|  | 
 | ||||||
|  | def rant_stats_per_weekday(): | ||||||
|  |     db = get_db() | ||||||
|  |     x = [] | ||||||
|  |     y = [] | ||||||
|  |     matplotlib.use('TkAgg') | ||||||
|  |     for record in db.query("SELECT * FROM rant_stats_per_weekday"): | ||||||
|  |         print(record) | ||||||
|  |         y.append(record['count']) | ||||||
|  |         x.append(str(record['weekday'])) | ||||||
|  | 
 | ||||||
|  |     plt.plot(x, y, label=get_date_range_str(), color='green') | ||||||
|  |     plt.xticks(rotation=20) | ||||||
|  |     plt.xlabel('Weekday') | ||||||
|  |     plt.ylabel('Rant count') | ||||||
|  |     plt.title('Rants per weekday') | ||||||
|  |     plt.legend() | ||||||
|  |     plt.savefig(f'export/rants_per_weekday_{get_date_range_str()}.png') | ||||||
|  |     plt.show() | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  | def rant_stats_per_hour(): | ||||||
|  |     db = get_db() | ||||||
|  |     x = [] | ||||||
|  |     y = [] | ||||||
|  |     matplotlib.use('TkAgg') | ||||||
|  |     for record in db.query("SELECT * FROM rant_stats_per_hour"): | ||||||
|  |         print(record) | ||||||
|  |         y.append(record['count']) | ||||||
|  |         x.append(record['hour']) | ||||||
|  | 
 | ||||||
|  |     plt.plot(x, y, label=get_date_range_str(), color='pink') | ||||||
|  |     plt.xticks(rotation=45) | ||||||
|  |     plt.xlabel('Hour') | ||||||
|  |     plt.ylabel('Rant count') | ||||||
|  |     plt.title('Rants per hour') | ||||||
|  |     plt.legend() | ||||||
|  |     plt.savefig(f'export/rants_per_hour_{get_date_range_str()}.png') | ||||||
|  |     plt.show() | ||||||
							
								
								
									
										55
									
								
								src/drstats/sync.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/drstats/sync.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | from drstats.devrant import Devrant | ||||||
|  | from drstats.db import get_db  | ||||||
|  | import json  | ||||||
|  | import asyncio | ||||||
|  | from pprint import pprint as pp | ||||||
|  | 
 | ||||||
|  | dr = Devrant() | ||||||
|  | db = get_db() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | from datetime import datetime  | ||||||
|  | 
 | ||||||
|  | def timestamp_to_string(timestamp): | ||||||
|  |     return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S') | ||||||
|  | 
 | ||||||
|  | async def get_recent_rants(start_from=1,page_size=10): | ||||||
|  |     page = 0 | ||||||
|  |     while True: | ||||||
|  |         rants = dr.get_rants('recent',page_size,start_from)['rants'] | ||||||
|  |         page += 1 | ||||||
|  |         for rant in rants: | ||||||
|  |             if rant is None:     | ||||||
|  |                 break  | ||||||
|  |             rant['tags'] = json.dumps('tags' in rant and rant['tags'] or '') | ||||||
|  |             rant['created'] = timestamp_to_string(rant['created_time']) | ||||||
|  |             rant = json.loads(json.dumps(rant,default=str)) | ||||||
|  |          | ||||||
|  |             for key,value in rant.items(): | ||||||
|  |                 if isinstance(value, list) or isinstance(value, dict): | ||||||
|  |                     value = json.dumps(value) | ||||||
|  |                     rant[key] = value | ||||||
|  | 
 | ||||||
|  |             yield rant  | ||||||
|  |         start_from += page_size | ||||||
|  | 
 | ||||||
|  | async def sync_rants(): | ||||||
|  |     count = 0; | ||||||
|  |     start_from = 0 #db['rants'].count() | ||||||
|  |     print(start_from) | ||||||
|  |     await asyncio.sleep(2) | ||||||
|  | 
 | ||||||
|  |     page_size = 20 | ||||||
|  | 
 | ||||||
|  |     async for rant in get_recent_rants(start_from,page_size): | ||||||
|  |         start_from += page_size | ||||||
|  |         count += 1 | ||||||
|  |         pp(rant) | ||||||
|  |         rant['tags'] = json.dumps(rant['tags']) | ||||||
|  |         db['rants'].upsert(rant,['id']) | ||||||
|  |         print(rant) | ||||||
|  |         print(f"Upserted {count} rant(s).") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def sync(): | ||||||
|  |     print(asyncio.run(sync_rants())) | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user