How to create and or edit a page with pyWikiBot - python

The MediaWiki API has an edit function which is available within pywikibot.
According to https://doc.wikimedia.org/pywikibot/master/api_ref/pywikibot.site.html
the function is called with a page parameter:
editpage(page, summary=None, minor=True, notminor=False, bot=True, recreate=True, createonly=False, nocreate=False, watch=None, **kwargs)[source]ΒΆ
A page needs a source to be constructed. I could not find an example for this.
E.g.: How to add something to edit summary when using Pywikibot?
has just one line as the accepted answer and does not use site or page. I am confused.
What is the proper approach do create and or edit a page with pyWikiBot directly using python code? (not script ...)
https://github.com/wikimedia/pywikibot/blob/master/pywikibot/page/init.py#L2328
has the constructor:
"""Page: A MediaWiki page."""
#deprecated_args(defaultNamespace='ns', insite=None)
def __init__(self, source, title='', ns=0):
"""Instantiate a Page object."""
if isinstance(source, pywikibot.site.BaseSite):
if not title:
raise ValueError('Title must be specified and not empty '
'if source is a Site.')
super(Page, self).__init__(source, title, ns)
Which is unfortunately not properly documented and part of the 6000 line init.py file having all the classes.
When trying
newPage=Page(site,pageTitle)
newPage.text=pageContent
I get
AttributeError: APISite instance has no attribute 'edit'
site.edit(newPage,'summary')

The following code works:
from pywikibot.page import Page
newPage=Page(site,pageTitle)
newPage.text=pageContent
newPage.save("summary")
see also https://www.mediawiki.org/wiki/Manual:Pywikibot/Create_your_own_script
It's just unfortunate that the documentation at https://pypi.org/project/pywikibot/ is not using standard python documentation tools.

Related

How to return new Selenium page object instance in a python method?

I need to return a new instance of page object using method in main page
I have an experience writing Selenium tests on java with page object model and I need to implement the same thing in Python.
Here's what I am struggling with:
I have a scenario that when I click on a link in method, the class instance of opening page object returns and I can work with methods of this new returned instance.
In java I can do it like that:
public class MainPage extends BasePage {
public SignInPage clickSignIn(){
clickElementByXpath(SIGN_IN_OPTION);
return new SignInPage();
}
}
How do I do that in Python?
Here is an example from a real project that I have, when I try to return page object instance and call method from it there is an error that self should be given as an argument.
class MainPage(BasePage):
def open_good_example_1(self):
"""Open good example 1 and return it's heading."""
example_heading = GoodExample1.is_heading_displayed(self)
return example_heading
class GoodExample1(BasePage):
"""Page object model for good menu example.
Search locators and methods are included here for Selenium tests.
"""
# Search locators
GOOD_MENU_EXAMPLE_HEADING = "//h1[#id='good-menu-example-heading']"
def is_heading_displayed(self):
"""Find and return heading to check if it is displayed in test."""
return self.find_element_by_xpath(self.GOOD_MENU_EXAMPLE_HEADING)
So, how can I call an instance of good example 1 in main page in Python as I can do it in Java?

How to create an atom template for python

I have the following class i am tired of writing it out every time. I need an atom template. For example if i were to type luigt and press enter the code would appear.
class TaskName(luigi.Task):
"""GENERAL TASK."""
def requires(self):
"""test."""
return None
def run(self):
"""test."""
pass
def output(self):
"""test."""
return luigi.LocalTarget('default')
Have a look to the snippets here.
You can define code snippets in there and a shortcut. I think this is exactly what you are looking for.
Extraction from the snippet page:
There is a text file in your ~/.atom directory called snippets.cson that contains all your custom snippets that are loaded when you launch Atom. You can also easily open up that file by selecting the Edit > Snippets menu.
Snippet Format
So let's look at how to write a snippet. The basic snippet format looks like this:
'.source.js':
'console.log':
'prefix': 'log'
'body': 'console.log(${1:"crash"});$2'
For more details, please have a look at the snippet page provided.

PRAW Errors updating to new Python Distro

So I am trying to create a bot that cross posts from a sub (r/pics) to (r/polpics) using a bit of code from u/GoldenSights. I upgraded to a new python distro and I get a ton of errors, I don't even know where to begin. Here is the code (formatting off, error lines bold):
Traceback (most recent call last):
File "C:\Users\tonyc\AppData\Local\Programs\Python\Python36-32\Lib\site-
packages\praw\subdump.py", line 84, in <module>
r = praw.Reddit(USERAGENT)
File "C:\Users\tonyc\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\praw\reddit.py", line 150, in __init__
raise ClientException(required_message.format(attribute))
praw.exceptions.ClientException: Required configuration setting 'client_id'
missing.
This setting can be provided in a praw.ini file, as a keyword argument to the `Reddit` class constructor, or as an environment variable.
This seems to be related to USERAGENT setting. I don't think I have that configured right.
USERAGENT = ""
# This is a short description of what the bot does. For example
"/u/GoldenSights' Newsletter bot"
SUBREDDIT = "pics"
# This is the sub or list of subs to scan for new posts.
# For a single sub, use "sub1".
# For multiple subs, use "sub1+sub2+sub3+...".
# For all use "all"
KEYWORDS = ["It looks like this post is about US Politics."]
# Any comment containing these words will be saved.
KEYDOMAINS = []
# If non-empty, linkposts must have these strings in their URL
This is the error line:
print('Logging in')
r = praw.Reddit(USERAGENT) <--here, this is error line 84
r.set_oauth_app_info(APP_ID, APP_SECRET, APP_URI)
r.refresh_access_information(APP_REFRESH)
Also in Reddit.py :
raise ClientException(required_message.format(attribute)) <--- error
praw.exceptions.ClientException: Required configuration setting 'client_id'
missing.
This setting can be provided in a praw.ini file, as a keyword argument to
the `Reddit` class constructor, or as an environment variable.
Firstly, you're going to want to have your API credentials stored externally in your praw.ini file. This makes things a lot more secure, and looks like it might go some way to fixing your issue. Here's what a completed praw.ini file looks like, including the useragent, so try to replicate this.
[DEFAULT]
# A boolean to indicate whether or not to check for package updates.
check_for_updates=True
# Object to kind mappings
comment_kind=t1
message_kind=t4
redditor_kind=t2
submission_kind=t3
subreddit_kind=t5
# The URL prefix for OAuth-related requests.
oauth_url=https://oauth.reddit.com
# The URL prefix for regular requests.
reddit_url=https://www.reddit.com
# The URL prefix for short URLs.
short_url=https://redd.it
[appname]
client_id=IE*******T14_w
client_secret=SW***********************CLY
password=******************
username=appname
user_agent=web:appname:1.0.0 (by /u/username)
Let me know how things go after you sort this out.

Upload file to CKAN with ckanapi (Python)

import ckanapi
try:
ckan = ckanapi.RemoteCKAN(serverurl,
apikey='myapikeyhere',
user_agent='useragenthere')
res = ckan.action.resource_create(
package_id='2ad3c9de-502c-403a-8b03-bfc619697ff2',
#url='url',
#revision_id='revid',
description='my first upload with CKANAPI',
upload=open('./upload.csv')
)
except Exception as e:
raise Exception(str(e.error_dict))
It fails with:
Field errors: {u'url': [u'Missing value'], u'__type': u'Validation Error'}
They made url a required attribute in this discussion on GitHub:
https://github.com/ckan/ckan/pull/1641
So what is the expected value of the url attribute?
If it's expecting the url to the local file, it's not hosted.
And I cannot supply the url of the file on CKAN, because the resourceid was not created, yet.
PS: When passing an arbitrary value for the url attribute, the upload succeeds.
It makes no sense to require the url attribute. Can anybody explain?
That's, in my opinion, a bug in CKAN. I've created a issue to track it at https://github.com/ckan/ckan/issues/2769. I've also wrote a pull request on ckanapi to abstract this bug at https://github.com/ckan/ckanapi/pull/74.
As a workaround in the mean time, you can set the url to an empty string.

pyfacebook + Google App Engine: can't find new functions in facebook.py

I'm trying to use the pyfacebook functions (https://github.com/sciyoshi/pyfacebook/) in a Google app engine project. I've followed the advice on the Facebook developer forum (http://forum.developers.facebook.net/viewtopic.php?pid=164613) and added the additional functions to the __init__.py file, copied that file to the root directory of my project and renamed it facebook.py. Having imported facebook.py I added the following to the get(self) method for the Python class for the page:
facebookapi = facebook.Facebook(API_KEY, SECRET)
if not facebookapi.check_connect_session(self.request):
path = os.path.join(os.path.dirname(__file__), 'templates/login.html')
self.response.out.write(template.render(path, {'apikey': API_KEY}))
return
user = facebookapi.users.getInfo(
[facebookapi.uid],
['uid', 'name', 'birthday', 'relationship_status'])[0]
template_values = {
'name': user['name'],
'birthday': user['birthday'],
'relationship_status': user['relationship_status'],
'uid': user['uid'],
'apikey': API_KEY
}
path = os.path.join(os.path.dirname(__file__), 'templates/index.html')
self.response.out.write(template.render(path, template_values))
When running it I get the following error:
File "\much\baw08u\Private\IDS\helloworld\helloworld.py", line 54, in get
if not facebookapi.check_connect_session(self.request):
AttributeError: 'Facebook' object has no attribute 'check_connect_session'
So it seems to be loading the facebook API fine, but not the new methods I've added. I copied and pasted the code from the developer forum at the bottom of the Facebook class definition, and made sure all the indentation was right but it still doesn't seem to be picking them up. Does anyone know what might be the problem?
Thanks
Ben
You believe the Facebook class has a certain method but Python is sure it hasn't. Why? Maybe you misspelled the method name, maybe you did not get the indentation right - hard to say without seeing the code.
You could try poking around to validate your assumptions:
import facebook
import logging
logging.warn('Facebook class: %r', dir(facebook.Facebook))
logging.warn('facebook module: %r', dir(facebook))
If you are sure you are operating on the correct file, the you should expect to see check_connect_session as a method of Facebook. If you didn't add enough indentation then you expect to see check_connect_method as a function defined in the facebook module. Too much indentation would make check_connect_method a sub function of which ever method precedes it and it won't show up in the above logging. Pay close attention to indentation.
However, a better way to add some custom methods might be:
import facebook
class Facebook(facebook.Facebook):
def check_connect_session(request):
pass
facebookapi = Facebook(API_KEY, SECRET)
if not facebookapi.check_connect_session(...):
...
Now when Facebook update their code you simply copy the new file into place - no need to merge your customisations.

Categories

Resources