def like_all(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[ Flarum_Likes.LikesExtension, absolutely_all.AbsolutelyAllExtension ]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin for posts in USER.absolutely_all_posts(): for post in posts: post: 'Flarum_Likes.LikesPostFromBulkMixin | Flarum_Likes.LikesPostFromDiscussionMixin' if not post.is_comment(): print(f"Post {post.id} is not a comment. Skipping.") continue try: liked = post.like() # type: Post print(f"Liked post {liked.id} ({liked.url})") except FlarumError: pass # time.sleep(1) continue
def test_groups(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password']) print("All groups:") for group in USER.get_groups(): print(f""" Singular: {group.nameSingular} Plural: {group.namePlural} Color: {group.color} Icon: {group.icon} Hidden: {'yes' if group.isHidden else 'no'} """) group_to_create = PreparedGroup(user=USER, nameSingular="Goomba", icon="fas fa-pastafarianism") created = group_to_create.create() print(f"""Created: Singular: {created.nameSingular} Plural: {created.namePlural} Color: {created.color} Icon: {created.icon} Hidden: {'yes' if created.isHidden else 'no'} """)
def test_messy_included(): USER = FlarumUser(forum_url="https://discuss.flarum.org") discussion = USER.get_discussion_by_id(28221) author = discussion.get_author() print(author.username, '=>', discussion.url)
def test_first_post(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password']) discussion = USER.get_discussions()[ 0] # discussion on top of the front page with default filters print(discussion.title) notifications = USER.get_notifications() notifications.mark_all_as_read()
def test_notifications(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[absolutely_all.AbsolutelyAllExtension]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin for notifications in USER.absolutely_all_notifications(): for notification in notifications: print(notification.id) if not notification.isRead: subject = notification.get_subject() if isinstance(subject, PostFromNotification): print(subject.content)
def test_advanced_search(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[ advanced_search.AdvancedSearchExtension ]) # type: advanced_search.AdvancedSearchFlarumUserMixin user = USER.get_user_by_username('test') if user: print(user.username) else: print("This user wasn't found.")
def test_lockdown(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[absolutely_all.AbsolutelyAllExtension, Flarum_Lock.LockExtension]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin for discussions in USER.absolutely_all_discussions(): for discussion in discussions: discussion: Flarum_Lock.LockDiscussionFromBulkMixin if not discussion.isLocked: locked = discussion.lock() print(f"Locked {locked.url}") else: print(f"{discussion.url} is already locked.")
def test_bio(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[ FoF_UserBio.UserBioExtension ]) # type: FoF_UserBio.UserBioFlarumUserMixin # Get random quote: quote = requests.get("http://api.quotable.io/random").json() # type: dict # Set it as your bio: updated = USER.update_user_bio( f"{quote['content']}\n\n- {quote.get('author', 'Unknown')}" ) # type: FlarumUser print(updated.data.bio) # type: ignore # can't type hint updated.data
def test_get_likes(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[Flarum_Likes.LikesExtension]) discussion = USER.get_discussions()[0].get_full_data() # type: Discussion for post in discussion.get_posts(): post: 'Flarum_Likes.LikesPostFromBulkMixin' liked_by = post.get_liked_by() if len(liked_by) > 0: print(f"Post {post.id} ({post.url}) was liked by:") for user in post.get_liked_by(): print(user.username)
def test_follow_all_ignored(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[ absolutely_all.AbsolutelyAllExtension, Flarum_Subscriptions.SubscriptionsExtension ]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin for discussions in USER.absolutely_all_discussions( Filter(query='is:ignored')): for discussion in discussions: discussion: Flarum_Subscriptions.SubscriptionsDiscussionFromBulkMixin discussion = discussion.follow() print( f"Now following ignored discussion {discussion.id} ({discussion.url})" )
def test_approve_unapproved(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[absolutely_all.AbsolutelyAllExtension, Flarum_Approval.ApprovalExtension]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin for discussions in USER.absolutely_all_discussions(): for discussion in discussions: full_discussion = discussion.get_full_data() for post in full_discussion.get_posts(): post: Flarum_Approval.ApprovalPostFromNotificationMixin if not post.isApproved: post.approve() print(f"Approved {post.url}") time.sleep(3) # prevent 429 else: print(f"{post.url} is already approved.")
def test_absolutely_all_posts(): USER = FlarumUser(forum_url="https://discuss.flarum.org", extensions=[ Flarum_Likes.LikesExtension, absolutely_all.AbsolutelyAllExtension ]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin discussion = USER.get_discussion_by_id(7585) for number, posts in enumerate( USER.get_all_posts_from_discussion(discussion)): if number > 3: # 3 batches of posts break for post in posts: print(post.url) print('-' * 20)
def test_post(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password']) to_post = PreparedDiscussion(user=USER, title='Test', content='testingy') posted = to_post.post() print(posted.url)
def test_upload(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[admin.AdminExtension]) # type: admin.AdminFlarumUserMixin # Get random birb image: birb_link = requests.get("https://some-random-api.ml/img/birb").json()['link'] birb_image = requests.get(birb_link, stream=True).content # Upload it as avatar: updated_user = USER.upload_user_avatar(birb_image) print(updated_user.data.avatarUrl) # ...or for someone else: _user = USER.get_user_by_id(3) USER.upload_user_avatar(birb_image, user=_user) print(USER.data.id) # Also, why not upload it as logo? USER.upload_logo(birb_image) # Remove uploaded favicon: USER.remove_favicon() print("OK")
def test_edit(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password']) # Edit first post of discussion with ID 16 to the current time. first_discussion = USER.get_discussions()[0].get_full_data() first_post = first_discussion.get_posts()[0] if first_post.contentType == 'comment': edited_content = f"""{first_post.content}\n###### BTW, The current time for me, the bot, is: {datetime.now().time().strftime(r"%H hours, %M minutes and %S seconds.")}.""" edit = PreparedPost(user=USER, discussion=first_discussion, content=edited_content) edited = first_post.edit(edit) print(f"Successfuly edited post {edited.id} - {edited.url}") else: print( f"First post of discussion ID {first_discussion.id} is not a comment (but {first_post.contentType}), editing that is not possible." )
def test_spamblock(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[ admin.AdminExtension, FoF_Spamblock.SpamblockExtension, Flarum_Suspend.SuspendExtension ]) ID_TO_BLOCK = 3 to_block = USER.get_user_by_id( ID_TO_BLOCK ) # type: FoF_Spamblock.SpamblockUserMixin | Flarum_Suspend.SuspendUserMixin blocked = to_block.spamblock() print(f"Success: {blocked}") try: to_block.suspend(suspended_for=timedelta(minutes=15)) print("Suspended for 15 minutes instead.") except FlarumError as error: print(f"Error: {error}")
from dotenv import load_dotenv load_dotenv() from pathlib import Path from pyflarum.client import FlarumUser from pyflarum.client.flarum.core.filters import Filter from pyflarum.client.extensions import absolutely_all from pyflarum.client.extensions.flarum import Flarum_Tags USER = FlarumUser(forum_url="https://discuss.flarum.org", extensions=[ absolutely_all.AbsolutelyAllExtension, Flarum_Tags.TagsExtension ]) # type: absolutely_all.AbsolutelyAllFlarumUserMixin # XXX: Can be done better by listing directly from the "Incompatible" tag def incompatible_extensions(): for discussions in USER.absolutely_all_discussions( Filter(order_by='createdAt')): for discussion in discussions: discussion: Flarum_Tags.TagsDiscussionMixin tags = discussion.get_tags() for tag in tags: if tag.name == "Incompatible": yield discussion
def test_something(): USER = FlarumUser(forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'])
from datetime import datetime from pathlib import Path try: from requests_cache.session import CachedSession as RSession except ImportError: from requests import Session as RSession from pyflarum.client import FlarumUser from pyflarum.client.flarum.core.filters import Filter from pyflarum.client.extensions import absolutely_all USER = FlarumUser(forum_url=os.environ['forum_url'], extensions=[absolutely_all.AbsolutelyAllExtension], session_object=RSession() ) # type: absolutely_all.AbsolutelyAllFlarumUserMixin def scrap_all(file_name: t.Union[str, bytes, Path] = "scrapped.html"): with open(file_name, 'w', encoding='UTF-8') as scrap: header = f"""<html><head><title>All discussions from {USER.forum_url}</title></head><body><div style="margin: 2rem 0; text-align: center; color: blue;"><h1>All discussions from <a href="{USER.forum_url}">{USER.forum_url}</a> ({datetime.now().strftime(r'%H:%M:%S %d. %m. %Y')})</h1></div><div id="data">\n""" scrap.write(header) for discussions in USER.absolutely_all_discussions( Filter(order_by="createdAt")): try: for _discussion in discussions: #time.sleep(5) # prevent 429 discussion = _discussion.get_full_data()
import os import requests from pyflarum.client import FlarumUser from pyflarum.client.flarum.core.notifications import Notification from pyflarum.client.flarum.core.posts import PostFromNotification, PreparedPost from pyflarum.client.extensions import watch from pyflarum.client.extensions import commands from pyflarum.client.extensions.flarum import Flarum_Likes USER = FlarumUser( forum_url=os.environ['forum_url'], username_or_email="test", password=os.environ['account_password'], extensions=[ watch.WatchExtension, commands.CommandsExtension, Flarum_Likes.LikesExtension ]) # type: watch.WatchFlarumUserMixin | commands.CommandsFlarumUserMixin API_KEY = os.environ['openweather_api_key'] WEATHER_POST_TEMPLATE = """**{city}**, `{country}` has **{weather}** and __{temperature} °C__""" def on_notification(notification: Notification): subject = notification.get_subject() if isinstance( subject, PostFromNotification): # if it's a notification about new post subject: Flarum_Likes.LikesPostFromNotificationMixin
def test_extensions(): USER = FlarumUser( forum_url=os.environ['forum_url'], username_or_email='test', password=os.environ['account_password'], extensions=[ Malago_Achievements.AchievementsExtension, admin.AdminExtension ] ) # type: admin.AdminFlarumUserMixin | Malago_Achievements.AchievementsAdminFlarumUserMixin # Update forum info: USER.update_forum_info( forum_description="Peppa Pig", forum_title="Hi, I am Peppa Pig *oink*", welcome_title="This is my little brother George", welcome_message="This is Mommy Pig", user_slug_driver= "And this is Daddy Pig", # surprisingly, this can be anything, even Daddy Pig default_route="/d/12") # Clear custom header: USER.update_custom_header() # Dynamic example: updating custom header to current time USER.update_custom_footer( f'<div style="text-align: center; padding: 20px 0;">Extension test was last run at {datetime.now()}</div>' ) # Validation test: raise FlarumError on invalid CSS: USER.update_custom_css('I am invalid.') # Enable achievements extension: USER.enable_extension(Malago_Achievements.AchievementsExtension.ID) all_achievements = USER.get_all_achievements() name = "test achievement" # Prevent double-creation: can_create = True for achievement in all_achievements: print(achievement.name) if achievement.name == name: can_create = False break # Create an achievement if can_create: USER.create_achievement(name="test achievements", description="owo", computation="year:1", points=100, image_url_or_fa_icon="fas fa-magic")